0

I am trying to compare nested multidimensional arrays by value and key so my scenario is:

I need to compare two nested multidimensional arrays and find the difference in terms of their values by quantity and update those quantities but also items which are in the new array and not the old one for example:

if I have the following data:

First Array:

Array (
    [0] => Array ( [name] => hey [qty] => 3 )  
    [1] => Array ( [name] => hello [qty] => 1 )  
    [2] => Array ( [name] => test [qty] => 1 )
)

And another nested multidimensional array with the following values:

Second Array:

Array (
    [0] => Array ( [name] => hey [qty] => 5 )  
    [1] => Array ( [name] => hello [qty] => 5 )  
    [2] => Array ( [name] => PHP [qty] => 2 )
)

I am trying to achieve the following output with only the new items by key in second array and update their values based upon the difference between the first and second array item's quantities i.e.:

Desired output

Array (
    [0] => Array ( [name] => hey [qty] => 2 )  
    [1] => Array ( [name] => hello [qty] => 4 )  
    [2] => Array ( [name] => PHP [qty] => 2 )
)

I am producing the difference using the following but note how PHP is not added. I am not too sure how to check for it in my inner for loop without adding it.

<?php

$items = [
    'hey',
    'hey',
    'hey',
    'hello',
    'test'
];

$arr = array_count_values($items);



$oldItems = array();
foreach ($arr as $name => $qty) {
    $oldItems[] = compact('name', 'qty');
}



$newItems = [
    ['name' => 'hey', 'qty' => 5],
    ['name' => 'hello', 'qty'=> 5],
    ['name' => 'PHP', 'qty' => 2]
];


$diff = [];

foreach($newItems as $newItem) {
    foreach($oldItems as $oldItem) {
        if ($newItem['name'] == $oldItem['name']) {
        //get quantity
            $qtyDiff = $newItem['qty'] - $oldItem['qty'];
          if ($qtyDiff > 0) {
             $diff[$newItem['name']] = $qtyDiff;
          }
        }
    }
}

print_r($diff); die();

My current output from this script is as follows:

Array (
    [0] => Array ( [name] => hey [qty] => 2 )  
    [1] => Array ( [name] => hello [qty] => 4 )
)  

Any help is appreciated or feedback on improvements. Thanks!

4
  • Have you considered using array_diff()? Commented Jan 13, 2016 at 18:38
  • I would definitely be interested in using the PHP built-in array functions but was not 100% sure on how to implement them when using a nested multidimensional array and it is not possible to flatten them (in my usage). Commented Jan 13, 2016 at 18:39
  • There is a complete example in the docs. Commented Jan 13, 2016 at 18:42
  • Note that your current script does not output a nested aray, but just Array ( [hey] => 2, [hello] => 4 ) Commented Jan 13, 2016 at 18:44

1 Answer 1

1

Only need one foreach:

<?php                                                                                                                                                                                                              

$oldItems = [                                                                                                                                                                                                      
    ['name' => 'hey', 'qty' => 3],                                                                                                                                                                                 
    ['name' => 'hello', 'qty'=> 1],                                                                                                                                                                                
    ['name' => 'test', 'qty' => 1]                                                                                                                                                                                 
];                                                                                                                                                                                                                 

$newItems = [                                                                                                                                                                                                      
    ['name' => 'hey', 'qty' => 5],                                                                                                                                                                                 
    ['name' => 'hello', 'qty'=> 5],                                                                                                                                                                                
    ['name' => 'PHP', 'qty' => 2]                                                                                                                                                                                  
];                                                                                                                                                                                                                 

$diff = array();                                                                                                                                                                                                   
foreach ($oldItems as $id => $oldRow) {                                                                                                                                                                            
    $newRow = $newItems[$id];                                                                                                                                                                                      
    if ($newRow['name'] == $oldRow['name']) {                                                                                                                                                                      
        $diff[] = array(                                                                                                                                                                                           
            'name' => $oldRow['name'],                                                                                                                                                                             
            'qty' => $newRow['qty'] - $oldRow['qty']                                                                                                                                                               
        );                                                                                                                                                                                                         
    } else {                                                                                                                                                                                                       
        $diff[] = $newItems[$id];                                                                                                                                                                                  
    }                                                                                                                                                                                                              
}                                                                                                                                                                                                                  

print_r($diff);

Output:

Array
(
    [0] => Array
        (
            [name] => hey
            [qty] => 2
        )

    [1] => Array
        (
            [name] => hello
            [qty] => 4
        )

    [2] => Array
        (
            [name] => PHP
            [qty] => 2
        )

)

If the order or size of old and new items are different, then use the following:

<?php                                                                                                                                                                                                              

$oldItems = [                                                                                                                                                                                                      
    ['name' => 'hey', 'qty' => 3],                                                                                                                                                                                 
    ['name' => 'hello', 'qty'=> 1],                                                                                                                                                                                
    ['name' => 'test', 'qty' => 1]                                                                                                                                                                                 
];                                                                                                                                                                                                                 

$newItems = [                                                                                                                                                                                                      
    ['name' => 'hey', 'qty' => 5],                                                                                                                                                                                 
    ['name' => 'hello', 'qty'=> 5],                                                                                                                                                                                
    ['name' => 'PHP', 'qty' => 2]                                                                                                                                                                                  
];                                                                                                                                                                                                                 
$name2newItem = array();                                                                                                                                                                                           
foreach ($newItems as $item) {                                                                                                                                                                                     
    $name2newItem[$item['name']] = $item;                                                                                                                                                                          
}                                                                                                                                                                                                                  

$diff = array();                                                                                                                                                                                                   
foreach ($oldItems as $id => $oldRow) {                                                                                                                                                                            
    $name = $oldRow['name'];                                                                                                                                                                                       
    if (isset($name2newItem[$name])) {                                                                                                                                                                             
        $newRow = $name2newItem[$name];                                                                                                                                                                            
        $diff[$name] = array(                                                                                                                                                                                      
            'name' => $name,                                                                                                                                                                                       
            'qty' => $newRow['qty'] - $oldRow['qty']                                                                                                                                                               
        );                                                                                                                                                                                                         
    }                                                                                                                                                                                                              
}                                                                                                                                                                                                                  
foreach ($name2newItem as $name => $item) {                                                                                                                                                                        
    if (!isset($diff[$name])) {                                                                                                                                                                                    
        $diff[$name] = $item;                                                                                                                                                                                      
    }                                                                                                                                                                                                              
}                                                                                                                                                                                                                  
$diff = array_values($diff);                                                                                                                                                                                       

print_r($diff);
Sign up to request clarification or add additional context in comments.

3 Comments

That worked perfectly and I see my mistakes in the original code. Thanks so much
One thing to note is that if the order is not exact then the array will not always calculate the difference correctly, is there a way to overcome this?
sure, see updated answer. just need an extra lookup array name2newItem

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.