0

I want to compare two arrays in php. My arrays looks like this

Array ( 
[0] => Array ( [Id] => 1 [row1] => 1458)
[1] => Array ( [Id] => 2 [row1] => 16) 
[2] => Array ( [Id] => 3 [row1] => 115) 
[3] => Array ( [Id] => 4 [row1] => 18) 
[4] => Array ( [Id] => 5 [row1] => 13) 
[5] => Array ( [Id] => 6 [row1] => 13) 
[6] => Array ( [Id] => 7 [row1] => 131)
)

Array ( 
[0] => Array ( [Id] => 1 [row1] => 158)
[1] => Array ( [Id] => 2 [row1] => 165) 
[2] => Array ( [Id] => 3 [row1] => 111) 
[3] => Array ( [Id] => 4 [row1] => 186) 
[4] => Array ( [Id] => 5 [row1] => 3)
)

Firstly, array1 size and array2 sizes were not equal always. Id value in array1 may or may not present in array2, If the value is not present, function have to print the total index in array3, like

[someindex] => Array ( [Id] => 6 [row1] => 13 )

if it is present, function should subtract the row1 of array1 to row1 of array2 and print in array3, like this

[someindex] => Array ( [Id] => 1 [row1] => 1300)

and my final output should be,

Array ( 
[0] => Array ( [Id] => 1 [row1] => 1300)
[1] => Array ( [Id] => 2 [row1] => -149) 
[2] => Array ( [Id] => 3 [row1] => 4) 
[3] => Array ( [Id] => 4 [row1] => -168) 
[4] => Array ( [Id] => 5 [row1] => 10) 
[5] => Array ( [Id] => 6 [row1] => 13) 
[6] => Array ( [Id] => 7 [row1] => 131)
)

Can any one help me in solving this problem.

0

4 Answers 4

1
$arr1 = Array ( 
    0 => Array ('Id' => 1, 'row1' => 1458)
    ,1 => Array ('Id' => 2, 'row1' => 16) 
    ,2 => Array ('Id' => 3, 'row1' => 115) 
    ,3 => Array ('Id' => 4, 'row1' => 18) 
    ,4 => Array ('Id' => 5, 'row1' => 13) 
    ,5 => Array ('Id' => 6, 'row1' => 13) 
    ,6 => Array ('Id' => 7, 'row1' => 131)
);
$arr2 = Array ( 
    0 => Array('Id' => 1, 'row1' => 158)
    ,1 => Array('Id' => 2, 'row1' => 165) 
    ,2 => Array('Id' => 3, 'row1'=> 111) 
    ,3 => Array('Id' => 4, 'row1' => 186) 
    ,4 => Array('Id' => 5, 'row1' => 3)
);
$final = array();
foreach($arr1 as $k => $sec)
{
    $sub = 0;
    foreach($arr2 as $sec2)
    {
        if($sec2['Id']==$sec['Id'])
        {
            $sub = $sec2['row1'];
            break;
        }
    }
    $sec['row1'] -= $sub;
    //Or to save to another element:
    //$sec['row2'] = $sec['row1']-$sub;
    $final[] = $sec;
}

echo '<pre>'.print_r($final,true).'</pre>';

Output:

Array ( 
    [0] => Array ( [Id] => 1 [row1] => 1300)
    [1] => Array ( [Id] => 2 [row1] => -149) 
    [2] => Array ( [Id] => 3 [row1] => 4) 
    [3] => Array ( [Id] => 4 [row1] => -168) 
    [4] => Array ( [Id] => 5 [row1] => 10) 
    [5] => Array ( [Id] => 6 [row1] => 13) 
    [6] => Array ( [Id] => 7 [row1] => 131)
)
Sign up to request clarification or add additional context in comments.

6 Comments

@Sreenath Do note that the actual Id value is not being used for the lookup.
@Sreenath Please note that my answer has been updated - as Jack quite rightly pointed out, this wasn't linking elements by the 'Id' element. It is now doing so correctly.
Modifying arrays in-place is a dangerous affair btw; what if you needed to use the old value of $arr1 again?
@Jack Yea I originally wrote the code with a new $final array, but figured I'd change it to just modify the original unless the OP specified otherwise, so as to not use duplicate data (larger array sizes could lead to pointless increase in memory usage, if we start adding extra copies)
But I don't want to disturb the first array, I want the output in another array.
|
0

First, you either have to make the second array searchable by using the Id value as the keys or write a search function. I'm choosing the former:

$searchable = array_reduce($array2, function(&$result, $item) {
    return $result + array($item['Id'] => $item['row1']);
}, array());

The array_reduce() function starts with an empty array and builds it using the array addition operator; this creates an array that can be dereferenced using the id.

Then you perform a map operation on the first array:

$array3 = array_map(function($item) use ($searchable) {
    $value = isset($searchable[$item['Id']]) ? $searchable[$item['Id']] : 0;
    $item['row1'] -= $value;
//    $item['row2'] = $item['row1'] - $value;
    return $item;
}, $array1);

Doing a map operation preserves the original array and creates a new one with the values you choose inside a callback function.

12 Comments

But, what if I had 10000 of records in my array? does it take time?
@Sreenath My tests have shown that this method is 75% slower than mine. Average with the above = 0.145, average with mine = 0.083. Though to be fair, I'm not sure at what size the gaps really start to appear, so it depends on what size arrays you're using
But jack, What If I want to save in diff in row2?
SmokeyPHP, I don't know your name but I had a same question for you.
@Sreenath The time for 10k records is small; small enough to not matter :) if you want to save the difference in another field, simply change $item['row1'] -= $value; with $item['row2'] = $item['row1'] - $value;.
|
0

Don't know if this exactly what you want, but you can check if a key exists with array_key_exists:

$array3 = array();
foreach ($array1 as $k => $v) {
        if (array_key_exists($k, $array2)) {
            $array3[] = $v - $array2[$k];
        } else {
            $array3[] = $v;
        }
    }

Comments

0

This creates an indexing array ($new) in case the main keys don't match of in the original arrays.

$arr = array ( 
    0 => array ( 'Id' => '1','row1' => 1458),
    1 => array ( 'Id' => '2','row1' => 16),
    2 => array ( 'Id' => '3','row1' => 115),
    3 => array ( 'Id' => '4','row1' => 18),
    4 => array ( 'Id' => '5','row1' => 13),
    5 => array ( 'Id' => '6','row1' => 13),
    6 => array ( 'Id' => '7','row1' => 131));
$arr2 = array ( 
    0 => array ( 'Id' => '1','row1' => 158),
    1 => array ( 'Id' => '2','row1' => 165),
    2 => array ( 'Id' => '3','row1' => 111),
    3 => array ( 'Id' => '4','row1' => 186),
    4 => array ( 'Id' => '5','row1' => 3));
$new = array();
foreach ($arr2 as $key => $value){
    $new[$value['Id']] = $value['row1'];
}
foreach ($arr as $key => $value){
    if (isset($new[$value['Id']])){
        $arr[$key]['row1'] -= $new[$value['Id']];
    }
}
print_r($arr);

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.