Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to combine php array of object by unique id?

I have these 2 arrays.

First array is from user input $cart:

$cart = [
   ['id' => 3, 'weight' => 20, 'percentage' => 80],
   ['id' => 1, 'weight' => 50, 'percentage' => 80],
   ['id' => 2, 'weight' => 40, 'percentage' => 80],
];

and second array, I do a database SELECT id, stock WHERE id IN (3,1,2), resulting $db_item

$db_item = [
    ['id' => 1, 'stock' => 9539.00],
    ['id' => 2, 'stock' => 9468.00],
    ['id' => 3, 'stock' => 9295.00],
];

I want to add the stock attribute in second array to first array. Expected output:

$cart = [
   ['id' => 3, 'weight' => 20, 'percentage' => 80, 'stock' => 9295.00],
   ['id' => 1, 'weight' => 50, 'percentage' => 80, 'stock' => 9539.00],
   ['id' => 2, 'weight' => 40, 'percentage' => 80, 'stock' => 9468.00],
];

This is what I tried, and it works, but I don't think it is necessary to have foreach, array_filter, and array_column:

foreach ($cart as $key => $cart_item) {
    $item = array_filter($db_item, function($item) use ($cart_item) {
        return $item['id'] === $cart_item['id'];
    });
    $cart[$key]['stock'] = array_column($item, 'stock')[0];
}

anyone has better idea how to optimize this?


EDIT: following Mohammad's answer, I can use more attribute in second array

$keys = [];
foreach ($arr2 as $item) {
    $keys[$item['id']] = array(
        'attr1' => $item['attr1'],
        'attr2' => $item['attr2'],
        // and so on
    );
}

$newArr = array_map(function($item) use($keys){
    $item['attr1'] = $keys[$item['id']]['attr1'];
    $item['attr2'] = $keys[$item['id']]['attr2'];
    // and so on
    return $item;
}, $arr1);

EDIT2: found out that we can simplify the foreach loop with just a single line using array_column.

$keys = array_column($arr2, null, 'id');

$newArr = array_map(function($item) use($keys){
    $item['attr1'] = $keys[$item['id']]['attr1'];
    $item['attr2'] = $keys[$item['id']]['attr2'];
    // and so on
    return $item;
}, $arr1);
like image 630
Christhofer Natalius Avatar asked Oct 17 '22 10:10

Christhofer Natalius


2 Answers

Use combination of array_flip() and array_column() to create array contain id and index of second array.

Then use array_map() to add new key stock to first array.

$keys = array_flip(array_column($arr2, 'id'));
$newArr = array_map(function($item) use($keys, $arr2){ 
    $item['stock'] = $arr2[$keys[$item['id']]]['stock'];
    return $item;
}, $arr1);

Check result in demo

Also you can use foreach instead of array_flip()

$keys = [];
foreach ($arr2 as $item)
    $keys[$item['id']] = $item['stock'];

$newArr = array_map(function($item) use($keys){ 
    $item['stock'] = $keys[$item['id']];
    return $item;
}, $arr1);

Check result in demo

like image 72
Mohammad Avatar answered Oct 27 '22 12:10

Mohammad


This can help too, one array_column + one array_map :

$arr2=array_column($arr2,'stock','id');
$arr1=array_map(function($val)use($arr2){$val['stock']=$arr2[$val['id']];return $val;},$arr1);
like image 37
Elementary Avatar answered Oct 27 '22 13:10

Elementary