Vortex
Vortex

Reputation: 816

Comparing nested multidimensional arrays

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!

Upvotes: 0

Views: 302

Answers (1)

Fabricator
Fabricator

Reputation: 12772

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

Upvotes: 1

Related Questions