如何比较数组的每个元素?

时间:2013-04-04 09:36:32

标签: php arrays unique

我想比较数组中的每个元素。

 $char=array();    
 for($i=0;$i<=10;$i++)
 {
        $char[$i]=rand(0,35);
 }

我想比较$ char数组的每个元素。如果有任何重复值,它应该更改值并选择另一个在数组中应该唯一的随机值。

7 个答案:

答案 0 :(得分:7)

在这个特殊的例子中,可能值的范围非常小,最好以另一种方式做到这一点:

$allPossible = range(0, 35);
shuffle($allPossible);

// Guaranteed exactly 10 unique numbers in the range [0, 35]
$char = array_slice($allPossible, 0, 10);

或使用array_rand的等效版本:

$allPossible = range(0, 35);
$char = array_rand(array_flip($allPossible), 10);

如果值的范围较大,那么这种方法会非常浪费,您应该在每次迭代时检查唯一性:

$char = array();
for ($i = 0; $i < 10; ++$i) {
    $value = null;

    // Try random numbers until you find one that does not already exist
    while($value === null || in_array($value, $char)) {
        $value = rand(0, 35);
    }

    $char[] = $value;
}

然而,这是一种概率方法,可能需要花费大量时间才能完成,具体取决于rand的输出是什么(如果您想要的值的数量接近,则会特别糟糕所有可能值的数量。)

此外,如果您想要选择的值的数量较大(假设超过50左右),那么in_array可能会成为瓶颈。在这种情况下,使用数组键检查唯一性而不是值应该更快,因为搜索键的存在是恒定时间而不是线性:

$char = array();
for ($i = 0; $i < 100; ++$i) {
    $value = null;

    // Try random numbers until you find one that does not already exist
    while($value === null || array_key_exists($char, $value)) {
        $value = rand(0, 1000);
    }

    $char[$value] = $value;
}

$char = array_values($char); // reindex keys to start from 0

答案 1 :(得分:0)

要更改随机值的任何重复值,您应该遍历数组两次:

$cont= 0;
foreach($char as $c){
    foreach($char as $d){
        if($c == $d){
            //updating the value
            $char[$cont] = rand(0,35);
        }
    }
    $cont++;
}

但我不知道的是,随机值是否也可以重复。在那种情况下,它不会那么简单。

答案 2 :(得分:0)

我从PHP Manual page for rand()

中获取了此代码
<?php
 function uniqueRand($n, $min = 0, $max = null)
 {
  if($max === null)
   $max = getrandmax();
  $array = range($min, $max);
  $return = array();
  $keys = array_rand($array, $n);
  foreach($keys as $key)
   $return[] = $array[$key];
  return $return;
 }
?>

此函数生成一个大小为$ n的数组,您可以像在rand中一样设置最小值和最大值。

所以你可以像

一样使用它
uniqueRand(10, 0, 35);

答案 3 :(得分:0)

首先在array_count_values()阵列上使用$char

然后你可以循环所有超过1的条目并随机化它们。你必须继续检查,直到所有计数都是1 tho。因为即使是随机也可能会重新制作副本。

答案 4 :(得分:0)

我建议制作随机数组的两个选项:

    <?php
    $questions = array(1, 2, 3, 4, 5, ..., 34, 35);
    $questions = shuffle($questions);
    ?>

之后你选择前10个元素。

答案 5 :(得分:0)

您可以尝试使用此代码替换任何重复的值。

for ($i = 0; $i < count($char); $i++) {
    for ($n = 0; $n < count($char); $n++) {
        if($char[$i] == $char[$n]){
            $char[$i] = rand(0,35);
        }
    }
}

答案 6 :(得分:0)

函数array_unique()从数组中获取所有唯一值,以第一次出现的方式键入。

函数array_diff()允许从另一个数组中的一个数组中删除值。

根据您需要如何拥有(或没有)键入的结果或保留键的顺序,您需要执行多个步骤。通常它的工作原理如下所示(使用PHP代码示例):

在数组中,您有NNu唯一的元素。

$N  = array(...);
$Nu = array_unique($N);

然后您需要替换重复项的随机元素r的数量是N减去Nu的计数。由于N的计数通常是有用的值,我还会将其分配给nc

$nc = count($N);
$r  = $nc - count($Nu);

这使r整数从0count(N) - 1

           0 : no duplicate values / all values are unique
           1 : one duplicate value / all but one value are unique
            ...
count(N) - 1 : all duplicate values / no unique value

因此,如果您需要零随机值($r === 0),则输入$N就是结果。这个边界条件是第二个最简单的结果(第一个简单的结果是没有成员的输入数组)。

对于所有其他情况,您需要r随机唯一值。在你的问题中,你从0到35写。但这不是完整的故事。想象一下,您的输入数组有36个重复值,每个数字在0到35之间重复一次。将0到35范围内的随机数再次添加到数组中会再次产生重复 - 保证。

相反,我已经阅读了您的问题,即您只是在寻找尚未成为输入数组一部分的唯一值。

因此,您不仅需要r随机值(Nr),而且到目前为止它们也不得属于NNu

要实现此目的,您只需创建count(N)个唯一值,请从这些值中删除唯一值Nu,以确保Nu中没有重复值。由于这是理论上的最大值而不是所需的确切数量,因此该数组用于从以下位置获取精确r元素的切片:

$Nr = array_slice(array_diff(range(0, $nc - 1), $Nu), 0, $r);

如果您还希望在订购range(0, $nc - 1)时随机添加这些新值,您可以执行以下操作:

shuffle($Nr);

这应该会使你似乎的随机性在你的问题中要求回到答案中。

现在,您可以在$Nu中获得原始数组r $Nr 中新值的独特部分。合并这两个数组将为您提供一个忽略key =&gt;的结果数组。值关系(数组是重新索引):

array_merge($Nu, $Nr);

例如array(3, 4, 2, 1, 4, 0, 5, 0, 3, 5)的示例$N,其结果为:

Array
(
    [0] => 3
    [1] => 4
    [2] => 2
    [3] => 1
    [4] => 0
    [5] => 5
    [6] => 7
    [7] => 9
    [8] => 6
    [9] => 8
)

正如您所看到的,所有唯一值(0-5)都在开头,然后是新值(6-9)。原始密钥不会被保留,例如价值5的关键最初为6,现在为5

关系或键=&gt;由于array_merge(),值不会保留,它会重新索引数字键。另外,Nr键中的唯一数字旁边也需要在数组中是唯一的。因此,对于添加到unqique现有数字的每个新数字,需要使用一个密钥作为重复数字的密钥。为了获得重复数字的所有密钥,原始数组中的密钥集减少了所有重复数字匹配的密钥集(&#34;唯一数组中的密钥&#34; $Nu):

$Kr  = array_keys(array_diff_assoc($N, $Nu));

现在可以使用这些键来锁定现有结果$Nr。 PHP中用于设置数组所有键的函数是使用函数array_combine()

$Nr = array_combine($Kr, $Nr);

这允许使用key =&gt;获得结果使用数组联合运算符(+保存的值关系:

$Nu + $Nr;

例如,使用上一个示例中的$N,其结果为:

Array
(
    [0] => 3
    [1] => 4
    [2] => 2
    [3] => 1
    [5] => 0
    [6] => 5
    [4] => 8
    [7] => 6
    [8] => 9
    [9] => 7
)

正如您现在可以看到的值5已保留密钥6以及密钥为0的值5在原始数组中,现在也在输出中,而不是像上一个示例中的键4

但是,由于现在已经为第一次出现的原始值保留了键,因此仍然会更改顺序:首先是所有先前唯一的值,然后是所有新值。但是,您可能希望添加新值。为此,您需要获取新值的原始键的顺序。这可以通过按键映射顺序和使用array_multisort()来基于该顺序进行排序来完成。

因为这需要通过参数传递返回值,这需要我从 V 字母开始引入的其他临时变量:

// the original array defines the order of keys:
$orderMap = array_flip(array_keys($N));

// define the sort order for the result with keys preserved
$Vt    = $Nu + $Nr;
$order = array();
foreach ($Vt as $key => $value) {
    $order[] = $orderMap[$key];
}

然后完成排序(此处使用保留键):

// sort an array by the defined order, preserve keys
$Vk = array_keys($Vt);
array_multisort($order, $Vt, $Vk);

结果是:

array_combine($Vk, $Vt);

再次使用上面的示例值:

Array
(
    [0] => 3
    [1] => 4
    [2] => 2
    [3] => 1
    [4] => 7
    [5] => 0
    [6] => 5
    [7] => 8
    [8] => 6
    [9] => 9
)

这个示例输出很好地显示了键从0到9排序,因为它们在输入数组中很好。与之前的输出相比,您可以看到第一个添加值7(键控4)位于第5个位置 - 与原始数组中的键值4相同。已经获得了键的顺序。

如果这是您努力的结果,您可以通过迭代原始数组键来快速切换到此步骤的路径,如果每个键都不是任何重复值的第一个值,您可以弹出改为使用新值数组:

$result = array();
foreach ($N as $key => $value) {
    $result[$key] = array_key_exists($key, $Nu) ? $Nu[$key] : array_pop($Nr);
}

再次使用示例数组值结果(与之前不同,因为$Nr被洗牌:

Array
(
    [0] => 3
    [1] => 4
    [2] => 2
    [3] => 1
    [4] => 7
    [5] => 0
    [6] => 5
    [7] => 8
    [8] => 9
    [9] => 6
)

最终可能是回答问题的最简单方法。希望这有助于您回答这个问题。请记住以下几点:

  • 分开你的问题:
    1. 您想知道某个值是否不合理 - array_unique()可以帮助您。
    2. 您想要创建X 唯一数字/值。 array_diff()可以帮到你。
  • 对齐流程:
    1. 首先获得唯一的数字。
    2. 首先获得新号码。
    3. 使用两者来处理原始数组。

就像这个例子一样:

// original array
$array = array(3, 4, 2, 1, 4, 0, 5, 0, 3, 5);

// obtain unique values (1.)
$unique = array_unique($array);

// obtain new unique values (2.)
$new = range(0, count($array) - 1);
$new = array_diff($new, $unique);
shuffle($new);

// process original array (3.)
foreach ($array as $key => &$value) {
    if (array_key_exists($key, $unique)) {
        continue;
    }
    $value = array_pop($new);
}
unset($value, $new);

// result in $array:
print_r($array);

然后(示例性因为shuffle($new))输出:

Array
(
    [0] => 3
    [1] => 4
    [2] => 2
    [3] => 1
    [4] => 9
    [5] => 0
    [6] => 5
    [7] => 8
    [8] => 7
    [9] => 6
)