I have arrays in this format and I would like to calculate a diff between 2 of them of the same type:
INPUT:
// ARR 1
[
[
'app_id' => '1234',
'right' => 'run',
],
[
'app_id' => '1234',
'right' => 'admin',
],
]
// ARR 2
[
[
'app_id' => '1234',
'right' => 'run',
],
[
'app_id' => '1234',
'right' => 'export',
],
]
OUTPUT:
// DIFF 'old_value'
[
[
'app_id' => '1234',
'right' => 'admin',
],
]
// DIFF 'new_value'
[
[
'app_id' => '1234',
'right' => 'export',
],
]
For other models, inner array may have set of different attributes, but they never mix up in such a fashion so that there are a some model 1 attributes and some model 2. They are always of one type, and diff is calculated between 2 of the same type.
That being said, I saw many similar questions, but they didn't quite answer my case so I actually found a solution like this:
// new and old are input arrays
$keys = array_keys(reset($new));
$implodeCallback = function ($value) use ($delimiter){
return implode($delimiter, $value);
};
// implode so I can use array_diff()
$oldValues = array_map($implodeCallback, $old);
$newValues = array_map($implodeCallback, $new);
// calculating diff
$diff['old_value'] = array_diff($oldValues, $newValues);
$diff['new_value'] = array_diff($newValues, $oldValues);
$combineCallback = function($item) use ($keys, $delimiter) {
return array_combine($keys, explode($delimiter, $item));
};
// Combining back to key=>value pairs as they were in the beginning.
$diff['old_value'] = array_map($combineCallback, $diff['old_value']);
$diff['new_value'] = array_map($combineCallback, $diff['new_value']);
While this works, I am somehow under the impression that this is not really good programming practice and I am concerned about performance if there are hundreds of records in the arrays. Is there a faster and more slick way to do this without doing quadruple foreach loops?