Как удалить повторяющиеся значения из многомерного массива в PHP - PullRequest
277 голосов
/ 21 ноября 2008

Как я могу удалить повторяющиеся значения из многомерного массива в PHP?

Пример массива:

Array
(
    [0] => Array
    (
        [0] => abc
        [1] => def
    )

    [1] => Array
    (
        [0] => ghi
        [1] => jkl
    )

    [2] => Array
    (
        [0] => mno
        [1] => pql
    )

    [3] => Array
    (
        [0] => abc
        [1] => def
    )

    [4] => Array
    (
        [0] => ghi
        [1] => jkl
    )

    [5] => Array
    (
        [0] => mno
        [1] => pql
    )

)

Ответы [ 17 ]

597 голосов
/ 03 июня 2009

Вот другой способ. Промежуточные переменные не сохраняются.

Мы использовали это для дедупликации результатов множества перекрывающихся запросов.

$input = array_map("unserialize", array_unique(array_map("serialize", $input)));
208 голосов
/ 22 августа 2013

Начиная с 5.2.9, вы можете использовать array_unique(), если вы используете флаг SORT_REGULAR, например:

array_unique($array, SORT_REGULAR);

Это позволяет функции сравнивать элементы на равенство, как если бы использовалось $a == $b, что идеально подходит для вашего случая.

Выход

Array
(
    [0] => Array
        (
            [0] => abc
            [1] => def
        )

    [1] => Array
        (
            [0] => ghi
            [1] => jkl
        )

    [2] => Array
        (
            [0] => mno
            [1] => pql
        )

)

Имейте в виду, однако, что документация гласит:

array_unique() не предназначен для работы с многомерными массивами.

56 голосов
/ 09 мая 2012

У меня была похожая проблема, но я нашел 100% рабочее решение для нее.

<?php
    function super_unique($array,$key)
    {
       $temp_array = [];
       foreach ($array as &$v) {
           if (!isset($temp_array[$v[$key]]))
           $temp_array[$v[$key]] =& $v;
       }
       $array = array_values($temp_array);
       return $array;

    }


$arr="";
$arr[0]['id']=0;
$arr[0]['titel']="ABC";
$arr[1]['id']=1;
$arr[1]['titel']="DEF";
$arr[2]['id']=2;
$arr[2]['titel']="ABC";
$arr[3]['id']=3;
$arr[3]['titel']="XYZ";

echo "<pre>";
print_r($arr);
echo "unique*********************<br/>";
print_r(super_unique($arr,'titel'));

?>
27 голосов
/ 21 ноября 2008

Другой способ. Сохранит и ключи.

function array_unique_multidimensional($input)
{
    $serialized = array_map('serialize', $input);
    $unique = array_unique($serialized);
    return array_intersect_key($input, $unique);
}
19 голосов
/ 21 ноября 2008

Комментарии пользователей к документации array_unique () имеют много решений для этого. Вот один из них:

kenrbnsn at rbnsn dot com
27 сентября 2005 г. 12: 09

Еще один Array_Unique для многомерных массивов. Я проверял это только на двухмерных массивах, но, вероятно, его можно обобщить для большего или использовать рекурсию.

Эта функция использует функции serialize, array_unique и unserialize для выполнения этой работы.


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://ca3.php.net/manual/en/function.array-unique.php#57202.

12 голосов
/ 21 мая 2016

Если «удалить дубликаты» означает «удалить дубликаты, но оставить их там», решение может состоять в том, чтобы сначала применить array_unique(...) к «столбцу идентификатора», а затем удалить в исходном массиве все ключи был удален из массива столбцов:

$array = [
    [
        'id' => '123',
        'foo' => 'aaa',
        'bar' => 'bbb'
    ],
    [
        'id' => '123',
        'foo' => 'ccc',
        'bar' => 'ddd'
    ],
    [
        'id' => '567',
        'foo' => 'eee',
        'bar' => 'fff'
    ]
];

$ids = array_column($array, 'id');
$ids = array_unique($ids);
$array = array_filter($array, function ($key, $value) use ($ids) {
    return in_array($value, array_keys($ids));
}, ARRAY_FILTER_USE_BOTH);

Результат:

Array
(
    [0] => Array
        (
            [id] => 123
            [foo] => aaa
            [bar] => bbb
        )

    [2] => Array
        (
            [id] => 567
            [foo] => eee
            [bar] => fff
        )

)
7 голосов
/ 23 февраля 2018
Array
(
    [0] => Array
        (
            [id] => 1
            [name] => john
        )

    [1] => Array
        (
            [id] => 2
            [name] => smith
        )

    [2] => Array
        (
            [id] => 3
            [name] => john
        )

    [3] => Array
        (
            [id] => 4
            [name] => robert
        )

)

$temp = array_unique(array_column($array, 'name'));
$unique_arr = array_intersect_key($array, $temp);

Это удалит дубликаты имен из массива. уникальный по ключу

3 голосов
/ 12 марта 2015

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

$uniqueArray = array_unique($array, SORT_REGULAR);
3 голосов
/ 08 ноября 2014

, если вам нужно устранить дубликаты на определенных ключах, таких как идентификатор mysqli, вот простая функция

function search_array_compact($data,$key){
    $compact = [];
    foreach($data as $row){
        if(!in_array($row[$key],$compact)){
            $compact[] = $row;
        }
    }
    return $compact;
}

Бонусные баллы Вы можете передать массив ключей и добавить внешний foreach, но он будет в 2 раза медленнее для каждого дополнительного ключа.

2 голосов
/ 07 августа 2015

если у вас есть такой массив:

(users - имя массива)

Array=>
 [0] => (array)
   'user' => 'john'
   'age' => '23'
 [1] => (array)
  'user' => 'jane'
  'age' => '20'
 [2]=> (array)
  'user' => 'john'
  'age' => '23'

и вы хотите удалить дубликаты ... затем:

$serialized = array();
for ($i=0; $i < sizeof($users); $i++) { 
  $test = in_array($users['user'], $serialized);
    if ($test == false) {
      $serialized[] = $users['user'];
    }
 }

может быть решением: P

...