根据相关的 id 列将数据从第二个二维数组添加到第一个二维数组

Add data from second 2d array to first 2d array based on related id columns

我有两个数组 $a 和 $b

$a = [
    '0' => [
        'name'=>'Apple',
        'id' => 1
    ],
    '1' => [
        'name'=>'Banana',
        'id' => 2
    ],
    '2' => [
        'name' => 'orange',
        'id' => 3
    ]
];

$b = [
    '0' => [
        'price'=> 20,
        'a_id' => 2
    ],
    '1' => [
        'price'=> 10,
        'a_id' => 3
    ],
    '3' => [
        'price'=> 30,
        'a_id' => 1
    ]
];

我正在尝试创建另一个带有 id(array $a), a_id (array $b) 映射的数组,我的输出如下所示:

$a = [
    '0' => [
        'id' => 1
        'name'=>'Apple',
        'price' => 30
    ],
    '1' => [
        'id' => 2
        'name'=>'Banana',
        'price' => 20
    ],
    '2' => [
         'id' => 3
         'name' => 'orange',
         'price' => 10
    ]
];

我试过数组映射

$combined = array_map(null,$a,$b);

但这个结果并不是我想要的结果。如何将我的第一个数组映射到 $a['id'] = $b['a_id'] 相关的第二个数组?

您可以按照以下方式进行:

foreach($a as $k => $item)
{        
    $price = 0;    

    foreach($b as $priceItem)
    {
       if($priceItem['a_id'] === $item['id'])
       {
            $price = $priceItem['price'];
            break;
       }   
    }

    $a[$k]['price'] = $price;
}

但是,这不是很有效,因为每个新价格和项目都会成倍地增加所需的循环。

如果您能够使用产品 ID 作为第一个数组中的键,您可以更有效地做到这一点:

// Key $a by product ID
$a = [
    1 => [
        'name'=>'Apple',
        'id' => 1
    ],
    2 => [
        'name'=>'Banana',
        'id' => 2
    ],
    3 => [
        'name' => 'orange',
        'id' => 3
    ]
];

foreach($b as $priceItem)
{   
    $a[$priceItem['a_id']]['price'] = $priceItem['price'];
}

您可以使用此代码

$result = [];

for($i=0; $i<sizeof($a); $i++){
    if(array_key_exists($i,$b)){
        $b[$i]['id']=$b[$i]['a_id'];
        unset($b[$i]['a_id']);
    }
    $result[] = array_merge($a[$i], array_key_exists($i,$b)?$b[$i]:array());
}

print_r($result);

这应该有效,如果数组 $b 中的项目没有价格,则将添加默认价格 0。

<?php

$result = [];

$t = array_column($b, 'a_id');

foreach($a as $k => $v) {
    
    $index = array_search($v['id'], $t);
    $v['price'] = $index !== FALSE ? $b[$index]['price'] : 0;
    $result[] = $v;

}

print_r($result);

?>

结果:

(
    [0] => Array
        (
            [name] => Apple
            [id] => 1
            [price] => 30
        )

    [1] => Array
        (
            [name] => Banana
            [id] => 2
            [price] => 20
        )

    [2] => Array
        (
            [name] => orange
            [id] => 3
            [price] => 10
        )
)

并不是说这样更有效,但可能更灵活、更易读。 就靠你了!

<?php

$a = [
    '0' => ['name'=>'Apple', 'id' => 1],
    '1' => ['name'=>'Banana', 'id' => 2],
    '2' => ['name' => 'orange', 'id' => 3],
    '3' => ['name' => 'extra', 'id' => 4]
];
$b = [
    '0' => ['price'=> 20, 'a_id' => 2],
    '1' => ['price'=> 10, 'a_id' => 3],
    '3' => ['price'=> 30, 'a_id' => 1]
];

$lookup = [];
foreach($b as $k => $v) {
    if (array_key_exists($v['a_id'], $lookup)) {
        // you have multiple prices... do something, throw an error, log an error, overwrite the value
        // what ever you want
    } else {
        // in case you have multiple array items you want to copy over
        // you can later merge the array
        // if its only ever going to be prices , you can just take the price instead of the unset
        $parent_id = $v['a_id'];
        unset($v['a_id']);
        $lookup[$parent_id] = $v;
    }
}

// in case you have more values that you want push, if nothing exists
$default_values = ['price' => 0];

foreach($a as $k => &$v) {

    if (array_key_exists($v['id'], $lookup)) {
        $v = array_merge($v, $lookup[$v['id']]);
    } else {
        $v = array_merge($v, $default_values);
    }

} 
/* bit less readable
foreach($a as $k => &$v)
    $v = array_merge($v, array_key_exists($v['id'], $lookup) ? $lookup[$v['id']] : $default_values);
*/
print_r($a);

结果

Array
(
    [0] => Array (
        [name] => Apple [id] => 1 [price] => 30
    )
    [1] => Array (
        [name] => Banana [id] => 2 [price] => 20
    )
    [2] => Array (
        [name] => orange [id] => 3 [price] => 10
    )
    [3] => Array (
        [name] => extra [id] => 4 [price] => 0
    )
)

注意避免嵌套 array_search() 调用,这不是最有效的方法。此任务应在每个阵列上打开时完成;换句话说,如果你想要最好的时间复杂度,不要多次迭代任何一个数组。

  1. 使用带有 null 第二个参数的 array_column() 临时分配 id 值作为一级键——这将使关联两个数组变得非常容易和高效。
  2. 我下面的代码片段将使用“数组解构”来解压缩 $b 数据并将 price 元素推送到结果集中。
  3. 循环完成后,使用 array_values() 到 re-index 输出数组(如果您愿意)。

代码:(Demo)

$result = array_column($a, null, 'id');
foreach ($b  as ['a_id' => $a_id, 'price' => $result[$a_id]['price']]);
var_export(array_values($result));

只是easy/simple.