比较两个数组并创建一个关联数组,其中包含true/false值。

7
我希望比较两个扁平化的、索引化的数组的值,并生成一个新的数组,其中键是第一个数组中的原始值,值是布尔值,表示相同的值是否在两个原始数组中都出现。
$array1 = [
    "car1",
    "car2",
    "car3",
    "car4",
    "car5"
];

$array2 = [
    "car1",
    "car4",
    "car5"
}

我尝试使用array_diff()函数比较这两个数组,但它给出的是元素值而不是布尔值。
我想要比较这两个数组中的每个值并生成一个“数组映射”,或者可以使用array_combine()函数得到如下的数组:
[
    "car1" => true,
    "car2" => false,
    "car3" => false
    "car4" => true,
    "car5" => true,
]
6个回答

8

数组很有趣!

PHP拥有大量的数组函数,因此有很多潜在的解决方案。

我提出了这个问题作为个人挑战,其中没有使用循环、过滤器或映射。

这个解决方案使用array_intersect来查找存在于两个数组中的值,然后使用array_valuesarray_fill_keys将它们转换为关联数组,并填充为TRUEFALSE,最后使用array_merge将它们合并成一个单一的数组:

$array1 = array( 0 => "car1", 1 => "car2", 2 => "car3", 3 => "car4", 4 => "car5");
$array2 = array( 0 => "car1", 1 => "car4", 2 => "car5" );

// Find all values that exist in both arrays
$intersect = array_intersect( $array1, $array2 );
// Turn it into an associative array with TRUE values
$intersect = array_fill_keys( array_values($intersect), TRUE );
// Turn the original array into an associative array with FALSE values
$array1 = array_fill_keys( array_values( $array1 ), FALSE );

// Merge / combine the arrays - $intersect MUST be second so that TRUE values override FALSE values
$results = array_merge( $array1, $intersect );

var_dump( $results ); 的结果为:

array (size=5)
  'car1' => boolean true
  'car2' => boolean false
  'car3' => boolean false
  'car4' => boolean true
  'car5' => boolean true

4

array_maparray_combine实际上并不返回您想要的内容。如果您想要使用array_map而无需编写foreach循环,下面的代码可以给您所需的结果。请注意,您必须将array3作为引用传递。

<?php 

$array1 = array( 0 => "car1", 1 => "car2", 2 => "car3", 3 => "car4", 4 => "car5");
$array2 = array( 0 => "car1", 1 => "car4", 2 => "car5" );
$array3 = [];

array_map(function($a) use ($array2, &$array3) {
    $array3[$a] = in_array($a, array_values($array2));
}, $array1);

var_dump($array3);

输出:

array(5) {
  ["car1"]=>
   bool(true)
  ["car2"]=>
   bool(false)
  ["car3"]=>
   bool(false)
  ["car4"]=>
   bool(true)
  ["car5"]=>
   bool(true)
}

在我看来,不使用array_map()的返回值是一种误用/滥用。如果你想用一个函数迭代一个数组,但不需要返回值,则应该使用array_walk() - mickmackusa

2

虽然速度较慢,但这应该能够满足您的需求,并且易于理解。

// Loop over the outer array which we're told has all the categories
$result = array();
foreach($array1 as $sCar1) {
  $found = false;

  // Loop over the categories of the post
  foreach($array2 as $sCar2) {

    // If the current post category matches
    // the current category we're searching for
    // note it and move on
    if($sCar2 == $sCar1) {
        $found = true;
        break;
    }
  }

  // Now indicate in the result if the post has the current category
  $result[$sCar1] = $found;
}

2
<?php
//EXAMPLE 1

$array1 = [0 => "car1", 1 => "car2", 2 => "car3", 3 => "car4", 4 => "car5"];
$array2 = [0 => "car1", 1 => "car4", 2 => "car5"];
$resultArray = [];

foreach ($array1 as $key => $val) {
    $resultArray[$val] = in_array($val, $array2);
}

var_dump($resultArray);
?>

<?php
//EXAMPLE 2

$array1 = [0 => "car1", 1 => "car2", 2 => "car3", 3 => "car4", 4 => "car5"];
$array2 = [0 => "car1", 1 => "car4", 2 => "car5"];
$resultArray = [];

$flipped = array_flip($array2);

foreach ($array1 as $key => $val) {
    $resultArray[$val] = isset($flipped[$val]);
}


var_dump($resultArray);

?>

结果:

array (size=5)
  'car1' => boolean true
  'car2' => boolean false
  'car3' => boolean false
  'car4' => boolean true
  'car5' => boolean true

2

使用array_count_values函数非常简单:

$results = array_map(function ($count) {
    return $count !== 1;
}, array_count_values(array_merge($array1, $array2)));

基本上,我们将两个数组合并在一起,然后计算值的出现次数。如果计数不等于1,则将值映射为true,否则为false。有趣的是,无论哪个数组较短,这都能够工作。 这里是演示
请注意,array_count_values函数对于每个不是字符串或整数的元素会抛出E_WARNING警告。因此,这种方法仅适用于字符串和整数数组。
此外,如果您的数组元素不唯一,则此方法可能失败,为此情况,您必须先对每个数组应用array_unique

0

使用迭代的in_array()调用或嵌套循环进行值比较可能不是最有效的方法,因为在PHP中,值比较比键比较慢。

进行键比较很快,但是不进行迭代比较会更快。通过依赖于数组在给定级别上不能具有重复键这一事实,只需将每个输入数组的元素更改为所需的布尔值,然后用第二个覆盖第一个即可。

代码:(演示)

var_export(
    array_replace(
        array_fill_keys($array1, false),
        array_fill_keys($array2, true),
    )
);

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