2

I have two arrays $a and $b

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

AND

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

I am trying to create another array with mapping with id(array $a), a_id (array $b), where my output will looks like:

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

I have tried by array map

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

But this result is not my desire result. How can I map my 1st array with 2nd array related by $a['id'] = $b['a_id']?

0

5 Answers 5

2

This should work, also if there's no price for an item in the array $b then the default price 0 will be added.

<?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);

?>

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
        )
)
Sign up to request clarification or add additional context in comments.

4 Comments

I am confused here for array_search in loop ? Is it efficient ?
yes, but it doesn't matter in micro-environments !!
Another problem is if I have another array element in array $a , then it getting wrong price. Example I added '4' => [ 'name' => 'charry', 'id' => 4 ] in $a array , then charry will get price 20.
@RezaulZablu edited my answer, please check :)
1

You can use this code

$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);

1 Comment

If I increase array $a element, this solution making error.My array $a element can be increase and it can be grater then array $b.
1

You can do it as follows:

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;
}

However, this isn't too efficient as every new price and item will exponentially increase the loops required.

If you are able to use the product IDs as the key in your first array, you could do it a lot more efficiently:

// 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'];
}

Comments

1

Not that this is more efficient, but maybe a bit more flexible, and readable. Its on you!

<?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);

result

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
    )
)

Comments

0

Be careful to avoid nested array_search() calls, this will not be the most efficient approach. This task should be completed with a On on each array; in other words, do not iterate either of the arrays more than once if you want the best possible time complexity.

  1. Use array_column() with a null 2nd parameter to temporarily assign id values as first level keys -- this will make relating the two arrays very easy and efficient.
  2. My snippet below will use "array destructuring" to unpack the $b data and push price elements into the result set.
  3. When the loop is finished, use array_values() to re-index the output array (if you wish).

Code: (Demo)

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

It's just that easy/simple.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.