1

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?

Norgul
  • 4,613
  • 13
  • 61
  • 144

0 Answers0