PHP многомерный массив удалить дубликат

Не уверен, что этот вопрос является дубликатом, нуждающимся в удалении, но я не смог найти ответ в другом месте, поэтому попробую спросить.

У меня есть массив 2d, который выглядит следующим образом:

Array
(
[0] => Array
    (
        [0] => dave
        [1] => jones
        [2] => [email protected]
    )

[1] => Array
    (
        [0] => john
        [1] => jones
        [2] => [email protected]

    )

[2] => Array
    (
        [0] => bruce
        [1] => finkle
        [2] => [email protected]
    )
)

Я хотел бы удалить тех, у кого есть повторяющиеся электронные письма. Итак, в приведенном выше примере я хотел бы просто удалить [][0] или [][2]. Я не беспокоюсь о проверке имен или чего-то подобного, мне просто нужно, чтобы подмассивы были дедуплицированы на основе одного значения.

На данный момент у меня есть что-то вроде этого

  if(is_array($array) && count($array)>0){
  foreach ($array as $subarray) {
    $duplicateEmail[$subarray[2]] = isset($duplicateEmail[$subarray[2]]);
    unset($duplicateEmail[$subarray[2]]);
   }
  }

но это просто неправильно. Любая помощь приветствуется.


person Kevin Carmody    schedule 07.12.2009    source источник
comment
возможный дубликат Как удалить повторяющиеся значения из многомерного массива в PHP   -  person Ja͢ck    schedule 22.08.2013


Ответы (6)


Быстрое решение, использующее уникальность индексов массива:

$newArr = array();
foreach ($array as $val) {
    $newArr[$val[2]] = $val;    
}
$array = array_values($newArr);

Примечание 1. Как видно из приведенного выше, последнее совпадение для адреса электронной почты используется вместо первого. Это можно изменить, заменив вторую строку на

foreach (array_reverse($array) as $val) {

Примечание 2: индексы в результирующем массиве несколько перепутаны. Но я думаю, это не имеет значения...

person Dan Soap    schedule 07.12.2009
comment
ваш 'for' должен был быть 'foreach', но в остальном он работает хорошо, спасибо. - person Kevin Carmody; 08.12.2009
comment
@Cassy - Только что превратил это в функцию для себя в маленьком приложении, которое я кодирую, спасибо за это! - person Shackrock; 21.04.2012
comment
Спасибо, человек, который добился цели. Не знаю, почему я сначала пропустил этот ответ. Теперь проблема решена! :) - person MR_AMDEV; 22.11.2018

Гораздо более простое решение.

$unique = array_map('unserialize', array_unique(array_map('serialize', $array)));

echo "<pre>";
print_r($unique);
person Dipesh Parmar    schedule 22.02.2013
comment
Это не отвечает на вопрос. Это просто проверяет уникальные массивы, а не их свойства. Тем не менее, ценю, что вы дали ему еще один шанс. - person Kevin Carmody; 23.02.2013
comment
@RishabhSeth рад, что это помогает вам - person Dipesh Parmar; 20.01.2016
comment
Работал как шарм, чтобы удалить дубликаты подмассивов для меня. - person Terry Carter; 07.10.2016

В комментариях пользователей для array_unique() есть несколько решений этой проблемы. Например

    function multi_unique($array) {
        foreach ($array as $k=>$na)
            $new[$k] = serialize($na);
        $uniq = array_unique($new);
        foreach($uniq as $k=>$ser)
            $new1[$k] = unserialize($ser);
        return ($new1);
    }

из http://uk.php.net/manual/en/function.array-unique.php#57202.

person robjmills    schedule 07.12.2009
comment
который охватывает весь подмассив, а не отдельные значения, если я не ошибаюсь - person Kevin Carmody; 07.12.2009

Пользователь SORT_REGULAR в качестве второго параметра.

$uniqueArray = array_unique($array, SORT_REGULAR);
person anghazi ghermezi    schedule 12.03.2015

Мое предложение:

protected function arrayUnique($array, $preserveKeys = false)
{
    $uniqueArray = array();
    $hashes = array();

    foreach ($array as $key => $value) {
        if (true === is_array($value)) {
            $uniqueArray[$key] = $this->arrayUnique($value, $preserveKeys);

        } else {
            $hash = md5($value);

            if (false === isset($hashes[$hash])) {
                if ($preserveKeys) {
                    $uniqueArray[$key] = $value;
                } else {
                    $uniqueArray[] = $value;
                }

                $hashes[$hash] = $hash;
            }
        }
    }

    return $uniqueArray;
}
person Vail    schedule 15.07.2013

Вы можете использовать умную функцию назначения клавиш array_column(), используя null в качестве второго параметра. Это назначает новые ключи каждому подмассиву, оставляя данные подмассива полностью нетронутыми. Эти временные ключи (элемент [2], также известный как «значения электронной почты») эффективно заставят новые подмассивы с повторяющимися электронными письмами перезаписывать предыдущие. Как только дубликаты удалены, просто переиндексируйте массив (при необходимости) с помощью array_values().

Код: (Демо)

$array = [
    ['dave', 'jones', '[email protected]'],
    ['john', 'jones', '[email protected]'],
    ['bruce', 'finkle', '[email protected]']
];

var_export(array_values(array_column($array, null, 2)));

Выход:

array (
  0 => 
  array (
    0 => 'bruce',
    1 => 'finkle',
    2 => '[email protected]',
  ),
  1 => 
  array (
    0 => 'john',
    1 => 'jones',
    2 => '[email protected]',
  ),
)
person mickmackusa    schedule 23.05.2018