多维数组比较两个数组并更新第一个数组值


Multidimenssion array compare two arrays and update first array value

我想用一个数字过滤一个数组,并更新它在第一个数组中的状态。

我有两个数组$arr1,$arr2

$arr1 = array(
    0=>array('number'=>100,name=>'john'),
    1=>array('number'=>200,name=>'johnny')
);
$arr2= array(
    0=>array('number'=>300,name=>'r'),
    1=>array('number'=>100,name=>'b'),
    2=>array('number'=>200,name=>'c')
);

最终输出应该是像这样的数组

$arr1 = array(
    0=>array('number'=>100,name=>'b'),
    1=>array('number'=>200,name=>'c')
);

有什么想法可以开始吗?

对于像这样的特殊数组修改,选择的方法是数组遍历。它允许您将自定义函数应用于给定数组中的每个元素。

现在,由于您的数据格式,您将不得不进行循环。Wrikken询问您是否可以检索或转换数据以提供更快的访问。下面的算法是O(n^2):它将需要与第一个阵列中的元素数量乘以第二个阵列中元素数量一样多的周期,或者确切地说是count($arr1) * count($arr2)

function updateNameFromArray($element, $key, $arr2) {
    foreach($arr2 as $value) {
        if($value['number'] == $element['number']) {
            $element['name'] == $value['name'];
            break;
        }
    }
}
array_walk($arr1, "updateNameFromArray", $arr2);

现在,Wrikken的建议是,如果您的数组可以改为'number'属性上的键控,那么搜索/替换操作会容易得多。因此,如果这是你的数据:

$arr1 = array(
    100=>array('number'=>100,name=>'john'),
    200=>array('number'=>200,name=>'johnny')
);
// notice the keys are 100 and 200 instead of 0,1
$arr2= array(
    300=>array('number'=>300,name=>'r'),
    100=>array('number'=>100,name=>'b'),
    200=>array('number'=>200,name=>'c')
);
// notice the keys are 300, 100 and 200 instead of 0,1, 2

然后,您可以在O(n)时间内完成此操作,只需在第一个数组上循环。

foreach($arr1 as $key => $value) {
    if(isset($arr2[$key])) {
        $value['number'] = $arr2[$key]['number'];
    }
}

试试这个。它没有那么干净,但我认为它会起作用。

<?php
 $arr1 = array(0=>array('number'=>100,'name'=>'john'),1=>array('number'=>200,'name'=>'johnny'));
 $arr2= array(0=>array('number'=>300,'name'=>'r'),1=>array('number'=>100,'name'=>'b'),2=>array('number'=>200,'name'=>'c'));
 foreach( $arr1 as $key=>$data1 )
  {
foreach( $arr2 as $key2=>$data2 )
{
    if( $data1['number'] == $data2['number'] )
    {
        $arr1[$key]['name'] = $arr2[$key2]['name'];
    }
 }
  }
 print_r( $arr1 );
?>

输出将是:

Array
(
[0] => Array
    (
        [number] => 100
        [name] => b
    )
[1] => Array
    (
        [number] => 200
        [name] => c
    )
)

没有一种简单的方法可以用通用的PHP函数实现这一点,因此,您可能需要创建映射数组。

我处理这个问题的方法是创建一个循环,该循环遍历第一个数组,并将数字值作为关键字映射到$arr1中它所在位置的索引,得到:

$tmp1 = array();
foreach ($arr1 as $key => $number_name) {
  $tmp1[$number_name['number']] = $key;
}

这应该会给你一个看起来像的数组

$tmp1 [
  100 => 0,
  200 => 1
];

然后,我将循环遍历第二个数组,获取数值,如果它作为$tmp1中的键存在,则获取相关的值(作为$arr1的键(,并使用它更新$arr1中的名称。

// Loop through $arr2
foreach ($arr2 as $number_name) {
  // Get the number value
  $number = $number_name['number'];
  // Find the $arr1 index 
  if (isset($tmp1[$number])) {
    $arr1_key = $tmp1[$number];
    // Set the $arr1 name value
    $arr1[$arr1_key]['name'] = $number_name['name'];
  }
}
<?php 
//Set the arrays
$arr1 = array(
    array('number'=>100,'name'=>'john'),
    array('number'=>200,'name'=>'johnny')
);
$arr2= array(
    array('number'=>300,'name'=>'r'),
    array('number'=>100,'name'=>'b'),
    array('number'=>200,'name'=>'c')
);
// use a nested for loop to iterate and compare both arrays
for ($i=0;$i<count($arr1);$i++):
    for ($j=0;$j<count($arr2);$j++):
        if ($arr2[$j]['number']==$arr1[$i]['number'])
            $arr1[$i]['name']=$arr2[$j]['name'];
    endfor;
endfor;
print_r($arr1);

输出:

 Array (
 [0] => Array ( [number] => 100 [name] => b )
 [1] => Array ( [number] => 200 [name] => c )
 )

话虽如此,您可能应该重新考虑数据的结构方式。你真的需要一个多维数组吗?还是可以使用一个简单的关联数组,比如

 // set the arrays
 $arr1 = array(
        'john'=>100,
        'johnny'=>200          
    );
 $arr2 = array(
       'r'=>300,
       'b'=>100,
       'c'=>200
     );
// find values in arr2 common to both arrays
$arr3 = array_intersect($arr2, $arr1);
// change the key of arr1 to match the corresponding key in arr2
  foreach ($arr3 as $key=>$value) {
      $old_key = array_search($value, $arr1);
      $arr1[$key]=$arr1[$old_key];
      unset($arr1[$old_key]);
  }

print_r($arr1);

输出:

Array ( 
   [b] => 100 
   [c] => 200 
)