blackandorangecat
blackandorangecat

Reputation: 1344

PHP combine array based on value, add 0 if no match

I have seen tons of questions that discuss portions of my question, but have been unable to work them into a solution. Hopefully someone can help me out.

I have two arrays, I'll call them Quantity and Shipping.


Here is Quantity:

Array(
    [0] => Array(
            [0] => 1
            [1] => Fed-Ex
        )
    [1] => Array(
            [0] => 2
            [1] => USPS
        )
    [2] => Array(
            [0] => 1
            [1] => USPS-E
        )
)

[0] is the quantity, and [1] is the name.


And here is Shipping:

Array(
    [0] => Array(
            [0] => 3
            [1] => Fed-Ex
        )
    [1] => Array(
            [0] => 1
            [1] => USPS
        )
    [2] => Array(
            [0] => 11
            [1] => USPS-A
        )
    [3] => Array(
            [0] => 10
            [1] => USPS-E
        )
)

[0] is the index, and [1] is the name.


I would like to combine them based on index 1 matches into something that looks like this. If there is no match I would like a 0 to be inserted instead (like in my USPS-A example).

I'll call it Master:

Array(
    [0] => Array(
            [0] => 3
            [1] => Fed-Ex
            [2] => 1
        )
    [1] => Array(
            [0] => 1
            [1] => USPS
            [2] => 2
        )
    [2] => Array(
            [0] => 11
            [1] => USPS-A
            [2] => 0
        )
    [3] => Array(
            [0] => 10
            [1] => USPS-E
            [2] => 1
        )
)

[0] is the index, [1] is the name, and [2] is the quantity.


Does anyone have any suggestions? I tried using nested foreach loops but I was ending up with duplicates even when I used break statements. Tried array_column and in_array as well but to no success.

Any help would be appreciated. Thank you.

Upvotes: 0

Views: 51

Answers (3)

Dariusz Majchrzak
Dariusz Majchrzak

Reputation: 1237

I think that would do the job (without nested loops):

<?php 

$quantities = [
    [1, 'Fed-Ex'],
    [2, 'USPS'],
    [1, 'USPS-E']
];

$shippings = [
    [3, 'Fed-Ex'],
    [1, 'USPS'],
    [11, 'USPS-A'],
    [10, 'USPS-E'],
];

foreach($quantities as &$v) {
    $quantities[$v[1]] = $v[0];
    unset($v);
}

$master = [];

foreach($shippings as $v) {
    $master[] = [
        $v[0], 
        $v[1], 
        isset($quantities[$v[1]]) ? $quantities[$v[1]] : 0
    ];
}

Upvotes: 0

Don&#39;t Panic
Don&#39;t Panic

Reputation: 41820

You don't need nested loops to do this. You can just loop over each of the arrays once.

First, iterate the $shipping array to build the $master array using the [1] key (name) as its index. You can add a zero value for quantity at index 2 at the same time.

foreach ($shipping as $s) {
    $master[$s[1]] = $s + [2 => 0];
}

Second, iterate the $quantity array to update the quantity values in $master.

foreach ($quantity as $q) {
    $master[$q[1]][2] = $q[0];
}

Keep in mind that with this approach, using the names as keys, if there are duplicate names they will be overwritten.

Upvotes: 1

Pascal Meunier
Pascal Meunier

Reputation: 715

If you assume that the shipping array will always be bigger than the quantity, here is something that works.

$quantities = [
    [1, 'Fex-Ex'],
    [2, 'USPS'],
    [1, 'USPS-E']
];

$shippings = [
    [3, 'Fex-Ex'],
    [1, 'USPS'],
    [11, 'USPS-A'],
    [10, 'USPS-E'],
];

$master = array();
foreach ($shippings as $shipping) {
    $qty = 0;
    foreach ($quantities as $quantity) {
        if ($shipping[1] == $quantity[1]) {
            $qty = $quantity[0];
        }
    }
    $master[] = array(
        $shipping[0],
        $shipping[1],
        $qty
    );
}

var_dump($master);

Upvotes: 1

Related Questions