Codeigniter 2.1,PHP - 从键值对中获取随机数组

I have query from which I need to take random values (random rows) and limit to, lets say, 5 results and subtract them from main array (query). How can I do this?

This is query function:

public function galerija_jedna_slike()
    {
        $galerija = $this->db->order_by('id_galerija', 'RANDOM')->limit(1)->get($this->table)->row();
        $q = " SELECT * FROM galerija_slike
                LEFT JOIN galerije
                ON galerija_slike.galerija_id = galerije.id_galerija
                WHERE galerija_id = $galerija->id_galerija ";
        return $this->db->query($q)->result_array();
    }

I managed to get random values, and now I need to remove those values from the main array. Function:

function array_random_assoc($arr, $num = 1) {
        $keys = array_keys($arr);
        shuffle($keys);

        $r = array();
        for ($i = 0; $i < $num; $i++) {
        $r[$keys[$i]] = $arr[$keys[$i]];
        }
        return $r;
    }

Load the entire table:

$gallery =  $this->db->query("SELECT * FROM gallery;");

Let choose five random rows from gallery:

$max_items = 5;
$num = $query->num_rows();
$row = $query->row(rand(0, $num - 1));
$minus = array(); //store the ids to include

for ($i = 0; $i < $max_items; $i ++)
    $minus[] = $gallery ->row(rand(0, $num - 1));

Iterate the gallery to build two arrays, 1. Gallery minus random rows 2. Random rows

$data = array();
foreach ($gallery ->result() as $row)
{
    if (in_array($row->id, $minus))
        $data['random'][] = $row
    else
        $data['gallery'][] = $row
}

Now, the array $data['gallery'] has all the items without the randon rows. And $data[random] is an array containing the random rows.

This should give some idea. Note: Code not tested.

public function galerija_jedna_slike()
{
    $galerija = $this->db->order_by('id_galerija', 'RANDOM')->limit(1)->get($this->table)->row();
    //query to get only id
    $q = "SELECT id FROM galerija_slike WHERE galerija_id = $galerija->id_galerija ";

    $result = $this->db->query($q)->result_array();

    $ids = array();
    foreach($result as $row){
        $ids[] = $row['id'];
    }

    //shuffle id arrays or other function to randomize
    shuffle($ids);

    $ids = array_slice($ids,0,5);//gets first 5 ids

    $sql = " SELECT * FROM galerija_slike
                    LEFT JOIN galerije
                    ON galerija_slike.galerija_id = galerije.id_galerija
                    WHERE galerija_id = $galerija->id_galerija AND id IN(".implode(',', $ids).")";

    return $this->db->query($sql)->result_array();
}

Your problem can be solved in 3 part.

  1. First the query. You have already done that and I will start from there.

  2. You need to generate 5 unique integer within the range of returned array. You also have to be careful in case less than 5 results are returned. Here is the code for that.

     $random_integer = array();
     for( $i=0; $i<5 && $i<(count($a)-1); $i++){
        while( 1 ){
            $random_value = rand(0, count($a)-1);
            if( in_array($random_value, $random_integer) ){
                continue;
            }
            else{
                $random_integer[] = $random_value;
                break;
           }
        }
     }
    

Now you have 5 unique random integer in $random_integer, within the range of your returned result. If less than 6 entries are returned from query, 1 will be used for normal post and rest will be used for random post. You can change that in the condition of for loop. in_array will check for any duplicate entry.

  1. The last part is to set these random queries in a separate variable and also truncate them from main queries. You can do it like this. Say, the returned query is $main_query

        foreach( $random_integer as $row ){
            $random_query[] = $main_query[$row];
            unset($main_query[$row]);
        }
        $main_query = array_values($main_query);
    

unset will not change the array keys. array_values function will normalize the array keys. Now $random_query will contain 5(max) random queries and $main_query will contain the rest of the queries.