PHP внутренний массив diff - PullRequest
       7

PHP внутренний массив diff

0 голосов
/ 29 января 2019

У меня есть массивы в этом формате, и я хотел бы рассчитать разницу между двумя из них одного типа:

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',
    ],
]

ВЫХОД:

// DIFF 'old_value'
[
    [
        'app_id' => '1234',
        'right' => 'admin',
    ],
]

// DIFF 'new_value'

[
    [
        'app_id' => '1234',
        'right' => 'export',
    ],
]

Для других моделей внутренний массив может иметь набор различных атрибутов, но они никогда не смешиваются таким образом, что есть некоторые атрибуты модели 1 и некоторая модель2. Они всегда одного типа, и diff рассчитывается между 2 одинакового типа.

При этом я видел много похожих вопросов, но они не совсем ответили на мой вопрос, поэтому я действительно нашел решение, подобное этому:

// 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']);

Хотя это работает, я как-топод впечатлением, что это не очень хорошая практика программирования, и я беспокоюсь о производительности, если в массивах есть сотни записей.Есть ли более быстрый и удобный способ сделать это без четырехкратных циклов foreach?

...