PHP检查数组每tot个元素是否包含特定值

3
我有一个如下所示的长数组。我需要实现的是检查这个数组中每6个元素是否都包含值为1。如果没有找到,则必须将其随机添加到其中6个元素之一(通过替换任何原始值)。另外,如果在每6个元素中发现该值超过2次,则需要将其中一个用另一个随机数字替换。
我已经编写了能够随机生成以下数组的代码。但是我不知道如何检查数组中每6个元素是否都包含值为1,如果没有找到该如何随机添加它,如果发现超过1次应当如何使用另一个随机数替换其中一个值。
简而言之,最终结果应该是:在每6个元素中,此数组必须至少包含一次值为1,并且不能超过一次,随机位于每6个元素中的某个位置。
到目前为止,我已经完成了以下工作,此代码生成以下数组:
/*
We select the elements to add randomly in the final array from a DB table
*/
    $elements = parent::$db->select('_matrix_elements', 'element_id', NULL, 'ORDER BY RAND()');
    $count = count($elements) - 1; //count the total number of the elements -1 to start from zero

    $columns = 6;
    $lines = 8;

    //generating the final array
    for ($a = 1; $a <= $lines; $a++) {
        for ($b = 1; $b <= $columns; $b++) {
            $rand = rand(1,$count);
            $line['position_'.$a.'_' . $b] = $elements[$rand]['element_id'];
        }
    }

Array
(
    [position_1_1] => 14
    [position_1_2] => 6
    [position_1_3] => 5
    [position_1_4] => 6
    [position_1_5] => 9
    [position_1_6] => 8
    [position_2_1] => 11
    [position_2_2] => 7
    [position_2_3] => 6
    [position_2_4] => 1
    [position_2_5] => 7
    [position_2_6] => 5
    [position_3_1] => 14
    [position_3_2] => 5
    [position_3_3] => 4
    [position_3_4] => 7
    [position_3_5] => 4
    [position_3_6] => 10
    [position_4_1] => 6
    [position_4_2] => 2
    [position_4_3] => 2
    [position_4_4] => 1
    [position_4_5] => 7
    [position_4_6] => 6
    [position_5_1] => 3
    [position_5_2] => 7
    [position_5_3] => 8
    [position_5_4] => 10
    [position_5_5] => 3
    [position_5_6] => 2
    [position_6_1] => 8
    [position_6_2] => 2
    [position_6_3] => 10
    [position_6_4] => 2
    [position_6_5] => 10
    [position_6_6] => 9
    [position_7_1] => 6
    [position_7_2] => 10
    [position_7_3] => 4
    [position_7_4] => 8
    [position_7_5] => 1
    [position_7_6] => 5
    [position_8_1] => 2
    [position_8_2] => 7
    [position_8_3] => 4
    [position_8_4] => 7
    [position_8_5] => 9
    [position_8_6] => 13
)

你考虑过使用二维数组吗?$position[7][4] = 8 - Madara's Ghost
@MadaraUchiha 我不明白它如何有所帮助。 - user2426701
不确定它是否真的有助于最初的原始问题。但是使用嵌套数组而不是编号名称将解决未来的许多问题。 - Madara's Ghost
@DiegoPucci - 你的描述有点不清楚,但我想我明白了。你想要设置一个数组,其中每个元素本身都是由6个数字组成的子数组;你想要检查这些子数组,对吗? - andrewsi
@andrewsi 不,数组已经是最终的了。我只需要在任意6个键中随机添加值1。因此,从p_1_1和p_1_6中必须有一个值为1,从p_2_1到p_2_6也是如此,依此类推。 - user2426701
2个回答

1
  1. 将列表拆分为二维数组,每个一维数组中有6个元素
  2. 计算每个元素在6个元素子数组中出现的次数
  3. 如果数组中没有1,则将随机元素变为1
  4. 如果数组中有2个或更多个1
  5. 用随机数字(不是1)替换,直到只剩下一个1
  6. 将最终的子数组添加到一个一维数组中
  7. 对2D数组中的所有子数组重复以上步骤
$list_2d = array_chunk($list, 6); 
$final_list = array();
foreach ($list_2d as $array) { 
    $count = array_count_values($array);
    if (!array_key_exists(1, $count))
        $array[mt_rand(0, 5)] = 1;
    else if ($count[1] > 1)
        for ($i = 1; $i <= $count[1] - 1; $i++)
            $array[array_search(1, $array)] = mt_rand(2, 15);
            //Use whatever random number you want here, as long as it's not 1
    $final_list = array_merge($final_list, $array);
}

0
最好一次性搞定,而不是为了修复它而制定另一个解决方案。尝试使用您的代码运行这两个函数。我也进行过测试,请在此处查看 http://phpfiddle.org/lite/code/i9e-gb3。希望这就是您需要的。
function randomizer($columns, $rows, $elements)
{
    $line = array();
    for ($row = 1; $row <= $rows; $row++)
    {
        $one_count = array();

        for ($col = 1; $col <= $columns; $col++)
        {
            $line['position_' . $row . '_' . $col] = randomID($elements);

            if ($line['position_' . $row . '_' . $col] == 1)
            {
                //we have 1 - store key value
                $one_count[] = 'position_' . $row . '_' . $col;
            }
        }

        if (empty($one_count))
        {
            //no 1 in last row - we will replace one random
            $rand_col = rand(1, $columns);
            $line['position_' . $row . '_' . $rand_col] = 1;
        }
        elseif (count($one_count) > 1)
        {
            //more than one 1 in last row, we will leave only one

            //first - pick one random to keep
            $keep_key = array_rand($one_count);
            unset($one_count[$keep_key]);

            // second - replace others with non 1 values
            foreach ($one_count as $repl_key)
            {
                //this time we won't take ID=1
                $line[$repl_key] = randomID($elements, true);
            }
        }
    }

    return $line;
}


function randomID($elements, $not1=false)
{
    $count = count($elements) - 1;

    $rand = rand(0, $count);
    $el_id = $elements[$rand]['element_id'];

    if ($not1 === true && $el_id == 1)
    {
        return randomID($elements, true);
    }

    return $el_id;
}

差点忘了,关于这个$rand = rand(0, $count); < 这是正确的方式。你已经做了$count = count($elements) - 1;,然后从1开始rand :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接