Laravel 5.7: Обнаружение дубликатов в коллекции на основе нескольких ключей (готово), но как переместить дубликаты в другую коллекцию? - PullRequest
0 голосов
/ 29 ноября 2018

У меня огромная коллекция данных (элементы массива).Каждый элемент должен различаться как дублирующий, если все значения для заданных ключей одинаковы. Представьте это как уникальный составной ключ .

$recordsAll = [
    ['unique1' => 'foo', 'unique2' => 'bar', 'whatever1' => 'whatever1'], // 1st OK
    ['unique1' => 'baz', 'unique2' => 'zaz', 'whatever2' => 'whatever2'], // 2nd OK
    ['unique1' => 'foo', 'unique2' => 'kkk', 'whatever3' => 'whatever3'], // 3rd OK (because unique2 is kkk not bar)
    ['unique1' => 'bar', 'unique2' => 'zaz', 'whatever4' => 'whatever4'], // 4th DUPE (dupe of the 2nd because on both unique1 is bar and unique2 is zaz)
];

В приведенном выше примере уникальный составной ключ представляет собой комбинацию unique и unique2.

IЯ могу удалить обманщиков.Я делаю это так:

$recordsAll = collect($recordsAll);
$recordsCleaned = $recordsAll->unique(function ($item) {
    return $item['unique1'].$item['unique2'];
});

Я могу подтвердить, что это работает, подсчитав результаты в обоих.Сбор со всем должен дать мне явно 4, в то время как очищенный должен дать мне 3, и они делают ...

dd($recordsAll->count(), $recordsCleaned->count()); // prints 4 and 3

Что я не знаю, как сделать (или, по крайней мере, у меня есть)идея, но она не работает), состоит в том, чтобы сохранить дублированные записи в другом массиве (коллекции).Так что я не хочу только удалять дупы и использовать очищенную коллекцию.Позже я также хочу выполнить некоторую логику для коллекции, содержащей дубликаты.

Я думал, что простой diff сделает работу за меня, , так как документация вполне понятна .

Метод diff сравнивает коллекцию с другой коллекцией или простым массивом PHP на основе ее значений.Этот метод возвращает значения в исходной коллекции, которых нет в данной коллекции:

$dupes = $recordsAll->diff($recordsCleaned);
$dupes->all();

Однако это не работает.Я тоже пробовал с diffAssoc и diffKeys.Пожалуйста, помогите мне, как я могу иметь 4-й (дублированный) элемент и все следующие дубликаты в совершенно новой коллекции?

edit:

Я придумал решение нижеНо я не думаю, что это хорошо с точки зрения производительности, поскольку в производственной коллекции будет почти миллионы предметов.

$recordsDupes = collect([]);
$recordsAll->each(function ($item) use ($recordsCleaned, $recordsDupes) {
    if ($recordsCleaned->contains($item) === false) {
        $recordsDupes->push($item);
    }
});

1 Ответ

0 голосов
/ 29 ноября 2018

Когда вы используете метод diff для коллекции, вы должны иметь коллекцию внутри коллекции в многомерном случае.Итак, ваш код должен выглядеть следующим образом:

$recordsAll = [
            ['unique1' => 'foo', 'unique2' => 'bar', 'whatever1' => 'whatever1'], // 1st OK
            ['unique1' => 'baz', 'unique2' => 'zaz', 'whatever2' => 'whatever2'], // 2nd OK
            ['unique1' => 'foo', 'unique2' => 'kkk', 'whatever3' => 'whatever3'], // 3rd OK (because unique2 is kkk not bar)
            ['unique1' => 'baz', 'unique2' => 'zaz', 'whatever4' => 'whatever4'], // 4th DUPE (dupe of the 2nd because on both unique1 is bar and unique2 is zaz)
        ];
$recordsAll = collect($recordsAll);

$recordsCleaned = $recordsAll->unique(function ($item) {
    return $item['unique1'].$item['unique2'];
});


$recordsAll = collect($recordsAll->toArray())->map(function($row) {
                                            return collect($row);
                                    });
$recordsCleaned = collect($recordsCleaned->toArray())->map(function($row) {
                                        return collect($row);
                                    });

$diff = $recordsAll->diff($recordsCleaned);

В приведенном выше коде переменная $diff будет коллекцией как разница между очищенным и всем.Я обработал все переменные в коллекции, и вы можете преобразовать их как массивы, если вам нужно.

Я думаю, вы поймете приведенный выше код, если возникнут какие-либо проблемы, не стесняйтесь спрашивать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...