как устранить повторяющиеся значения [duplicate]

Очень простой и логичный способ для уникального многомерного массива выглядит следующим образом:

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

  Array ([Key1] = & gt;  Массив ([0] = & gt; Value1 [1] = & gt; Value2 [2] = & gt; Value1 [3] = & gt; Value3 [4] = & gt; Value1) [Key2] = & gt; Array ([0]  = & gt; Value1 [1] = & gt; Value2 [2] = & gt; Value1 [3] = & gt; Value3 [4] = & gt; Value4))  

использовать foreach , чтобы решить эту проблему:

  foreach ($ array as $ k = & gt; $ v) {$ unique = array_unique ($ v);  $ Массив [$ к] = $ уникальный;  }  

он даст вам следующий результат:

  Array ([Key1] = & gt; Array ([0] = & gt; Value1 [1] =  & gt; Value2 [3] = & gt; Value3) [Key2] = & gt; Array ([0] = & gt; Value1 [1] = & gt; Value2 [3] = & gt; Value3 [4] = & gt; Value4)) [  ! d3] 

, и если вы хотите изменить порядок ключей,

  foreach ($ array as $ k = & gt; $ v) {$ unique = array_values  (array_unique ($ v));  $ Массив [$ к] = $ уникальный;  }  

Эта операция даст вам упорядоченные значения ключей следующим образом:

  Массив ([Ключ1] = & gt; Массив ([0] = & gt; Value1  [1] = & gt; Value2 [2] = & gt; Value3) [Key2] = & gt; Массив ([0] = & gt; Value1 [1] = & gt; Value2 [2] = & gt; Value3 [3] = & gt;  Value4))  

Надеюсь, это очистит все.

246
задан Ian 21 November 2008 в 03:50
поделиться

17 ответов

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

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

  $ input = array_map ("unserialize", array_unique (array_map ("serialize", $  вход)));   
555
ответ дан jeromegamez 16 August 2018 в 07:56
поделиться
  • 1
    Из-за unserialize это медленнее и медленнее, чем больше и сложнее массив. Есть причина, по которой я использовал array_intersect_key (полгода до этого ответа). – OIS 9 February 2013 в 01:00
  • 2
    @OIS хорошо протестировал его, имел опечатку, но он работает .. спасибо dude !: $ no_duplicates = array_intersect_key ($ array, array_unique (array_map ('serialize', $ array))); – trevorkavanaugh 3 June 2013 в 21:26
  • 3
    если вы хотите, чтобы индекс был непрерывным, используйте array_values, т. е. $ input = array_values ​​(array_map («unserialize», array_unique (array_map («serialize», $ input))); – lbsweek 17 April 2014 в 11:44
  • 4
    В настоящее время вы, вероятно, предпочтете json_encode и json_decode вместо сериализации PHP. должен иметь преимущества для предоставленных значений и , которые вы не используете в деталях сериализации PHP, которые сериализуют / неэриализуют корабли и, скорее всего, нежелательны. – hakre 23 August 2014 в 14:38
  • 5
    Помните, что serialize (array ('a' = & gt; '1', 'b' = & gt; '1')) отличается от serialize (array ('b' = & gt; '1', 'a' = & gt; '1')) . Эта опция не будет использоваться для массивов, используемых в качестве наборов или (хэш) карт . – Andras Gyomrey 19 October 2016 в 14:49

Очень простой и логичный способ для уникального многомерного массива выглядит следующим образом:

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

  Array ([Key1] = & gt;  Массив ([0] = & gt; Value1 [1] = & gt; Value2 [2] = & gt; Value1 [3] = & gt; Value3 [4] = & gt; Value1) [Key2] = & gt; Array ([0]  = & gt; Value1 [1] = & gt; Value2 [2] = & gt; Value1 [3] = & gt; Value3 [4] = & gt; Value4))  

использовать foreach , чтобы решить эту проблему:

  foreach ($ array as $ k = & gt; $ v) {$ unique = array_unique ($ v);  $ Массив [$ к] = $ уникальный;  }  

он даст вам следующий результат:

  Array ([Key1] = & gt; Array ([0] = & gt; Value1 [1] =  & gt; Value2 [3] = & gt; Value3) [Key2] = & gt; Array ([0] = & gt; Value1 [1] = & gt; Value2 [3] = & gt; Value3 [4] = & gt; Value4)) [  ! d3] 

, и если вы хотите изменить порядок ключей,

  foreach ($ array as $ k = & gt; $ v) {$ unique = array_values  (array_unique ($ v));  $ Массив [$ к] = $ уникальный;  }  

Эта операция даст вам упорядоченные значения ключей следующим образом:

  Массив ([Ключ1] = & gt; Массив ([0] = & gt; Value1  [1] = & gt; Value2 [2] = & gt; Value3) [Key2] = & gt; Массив ([0] = & gt; Value1 [1] = & gt; Value2 [2] = & gt; Value3 [3] = & gt;  Value4))  

Надеюсь, это очистит все.

1
ответ дан Anand agrawal 16 August 2018 в 07:56
поделиться

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

  $ uniqueArray = array_unique ($ array, SORT_REGULAR);   
3
ответ дан anghazi ghermezi 16 August 2018 в 07:56
поделиться
  • 1
    что не работает для многомерных массивов. – r3wt 17 March 2015 в 00:42
  • 2
    SORT_REGULAR работает только в PHP 7, потому что PHP 5 имеет ошибку (хотя @ r3wt является правильным в соответствии с документацией), см. Мой комментарий в ответе для запускаемого примера stackoverflow.com/questions/307674/… – Zack Morris 21 September 2016 в 01:42
  • 3
    Почему бы вам добавить это? Это то же самое, что и этот ответ, который на год старше вашего: stackoverflow.com/a/18373723/870729 – cale_b 14 April 2017 в 20:27

Как говорят люди array_unique () очень медленно, вот фрагмент, который я использую для одномерного многомерного массива.

  $ serialized_array = array_map ("сериализовать  ", $ input);  foreach ($ serialized_array как $ key = & gt; $ val) {$ result [$ val] = true;  } $ output = array_map ("unserialize", (array_keys ($ result)));   

Ссылка, сделанная первым пользователем, посвященная array_unique () странице функции в php.net

0
ответ дан Anuj 16 August 2018 в 07:56
поделиться
  • 1
    Анудж, не могли бы вы отредактировать свой ответ? Есть ошибка. Он должен завершиться $ output = array_map ('unserialize', array_keys ($ result)); – keyboardSmasher 16 May 2015 в 15:18
  • 2
    @keyboardSmasher благодарю вас за ваш вклад. Я внес изменения, и теперь он работает. :) – Anuj 22 May 2015 в 13:07

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

  $ array = [['id' = & gt;  '123', 'foo' = & gt;  'aaa', 'bar' = & gt;  'bbb'], ['id' = & gt;  '123', 'foo' = & gt;  'ccc', 'bar' = & gt;  'ddd'], ['id' = & gt;  '567', 'foo' = & gt;  'eee', 'bar' = & gt;  '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);   

Результат:

  Массив ([0] = & gt; Массив ([id] = & gt; 123 [foo] = & gt; aaa [  bar] = & gt; bbb) [2] = & gt; Массив ([id] = & gt; 567 [foo] = & gt; eee [bar] = & gt; fff))  
11
ответ дан automatix 16 August 2018 в 07:56
поделиться

Альтернатива сериализации и уникальности

  $ test = [['abc', 'def'], ['ghi', 'jkl'],  ['mno', 'pql'], ['abc', 'def'], ['ghi', 'jkl'], ['mno', 'pql'],];  $ result = array_reduce ($ test, function ($ carry, $ item) {if (! in_array ($ item, $ carry)) {array_push ($ carry, $ item);} return $ carry;}, []);  var_dump ($ результат);  / * php unique.php array (3) {[0] = & gt;  array (2) {[0] = & gt;  строка (3) "abc" [1] = & gt;  string (3) "def"} [1] = & gt;  array (2) {[0] = & gt;  строка (3) "ghi" [1] = & gt;  string (3) "jkl"} [2] = & gt;  array (2) {[0] = & gt;  string (3) "mno" [1] = & gt;  string (3) "pql"}}  

* /

0
ответ дан Denis Laliberté 16 August 2018 в 07:56
поделиться

Легко читаемое решение, возможно, не самое эффективное:

  function arrayUnique ($ myArray) {if (! is_array ($ myArray)) возвращает $ myArray;  foreach ($ myArray as & amp; $ myvalue) {$ myvalue = serialize ($ myvalue);  } $ myArray = array_unique ($ myArray);  foreach ($ myArray as & amp; $ myvalue) {$ myvalue = unserialize ($ myvalue);  } return $ myArray;  }  
1
ответ дан graham.reeds 16 August 2018 в 07:56
поделиться

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

  array_unique ($ array  , SORT_REGULAR);   

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

Выход

  Массив ([0] = & gt; Массив ([0] = & gt; abc [1] = & gt; def) [1] = & gt; Массив ([0] =  & gt; ghi [1] = & gt; jkl) [2] = & gt; Массив ([0] = & gt; mno [1] = & gt; pql))  

Имейте в виду, хотя заявляет в документации :

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

181
ответ дан Ja͢ck 16 August 2018 в 07:56
поделиться
  • 1
    Думаю, это более быстрое и четкое решение, чем принятое! давайте голосовать за это! :) Хммм на сайте php мы видим, что это не так быстро, как я думал ... – Andron 5 May 2015 в 10:50
  • 2
    Странно, что использование флага SORT_REGULAR просто не работает для меня, чтобы удалить повторяющиеся массивы. – Stefan 30 July 2015 в 08:28
  • 3
    @Stefan Вы правы; он, похоже, не дает правильных результатов, но, вероятно, это ошибка, потому что он работает с PHP 7 = / – Ja͢ck 30 July 2015 в 09:25
  • 4
    Это также работает в моем случае, но кто-то еще беспокоил эту заметку в документе array_unique ()? [D0] php.net/manual/en/&hellip – Arleigh Hix 2 May 2016 в 18:46
  • 5
    @Jack. Вы правы, это ошибка с PHP 5.6.23: eval.in/645675 , но исправлена ​​с PHP 7.0.8: eval.in/645676 – Zack Morris 21 September 2016 в 01:40

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

(пользователи - это имя массива)

  Array = & gt;  [0] = & gt;  (массив) 'user' = & gt;  'john' 'age' = & gt;  '23' [1] = & gt;  (массив) 'user' = & gt;  'jane' 'age' = & gt;  '20' [2] = & gt;  (массив) 'user' = & gt;  'john' 'age' = & gt;  '23'  

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

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

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

2
ответ дан Limon 16 August 2018 в 07:56
поделиться

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

Прежде всего, спасибо @jeromegamez @daveilers для вашего решения. Но каждый раз, когда я давал ответ, они спрашивали меня, как это «сериализовать» и «неэриализовать». Вот почему я хочу поделиться с вами причиной этого, чтобы он помог большему количеству людей понять концепцию, стоящую за этим.

Я объясняю, почему мы используем «serialize» и «unserialize» в шагах:

Шаг 1: Преобразование многомерного массива в одномерный массив

To преобразовать многомерный массив в одномерный массив, сначала сгенерировать представление потока байтов всех элементов (включая вложенные массивы) внутри массива. Функция serialize () может генерировать представление байтового потока значения. Чтобы генерировать представление байтов по всем элементам, вызовите функцию serialize () внутри функции array_map () как функцию обратного вызова. Результат будет одномерным массивом независимо от того, сколько уровней имеет многомерный массив.

Шаг 2: Сделайте уникальные значения

Чтобы сделать этот одномерный массив уникальным, используйте array_unique ( ).

Шаг 3: Верните его в многомерный массив

. Хотя массив теперь уникален, значения выглядят как представление потока байтов. Чтобы вернуть его обратно к многомерному массиву, используйте функцию unserialize ().

  $ input = array_map («unserialize», array_unique (array_map («serialize», $ input)));   

Еще раз спасибо за все это.

0
ответ дан Manish 16 August 2018 в 07:56
поделиться

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

kenrbnsn at rbnsn dot com 27-Sep-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 .

18
ответ дан ManuSharma 16 August 2018 в 07:56
поделиться

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

  & lt;? php function super_unique ($ array, $ key) {$ temp_array = [];  foreach ($ array as & amp; $ v) {if (! isset ($ temp_array [$ v [$ key]])) $ temp_array [$ v [$ key]] = & amp;  $ V;  } $ array = array_values ​​($ temp_array);  return $ array;  } $ arr = "";  $ Обр [0] [ 'ID'] = 0;  $ Обр [0] [ 'TITEL'] = "ABC";  $ Обр [1] [ 'ID'] = 1;  $ Обр [1] [ 'TITEL'] = "DEF";  $ Обр [2] [ 'ID'] = 2;  $ Обр [2] [ 'TITEL'] = "ABC";  $ Обр [3] [ 'ID'] = 3;  $ Обр [3] [ 'Titel'] = "XYZ";  echo "& lt; pre & gt;";  print_r ($ обр);  echo "unique ********************* & lt; br / & gt;";  print_r (super_unique ($ обр 'Titel'));  ? & GT;   
49
ответ дан Martin 16 August 2018 в 07:56
поделиться
  • 1
    Я удивлен, что никто не любит эту функцию. Это дает возможность удалять дубликаты на основе 1 внутреннего значения (не всей записи). Это отличный способ удалить повторяющиеся IP-адреса из журнала, где в тот же день может быть несколько соединений. – doubleJ 6 September 2012 в 16:29
  • 2
    Это отвечает на другой вопрос. См. Здесь: stackoverflow.com/questions/4585208/… – OIS 9 February 2013 в 01:28
  • 3
    Отличная функция! и если вы имеете дело с объектами: if (! isset ($ array- & gt; $ v- & gt; $ key)) $ array [$ v- & gt; $ key] = & amp; $ V; – Playnox 17 March 2016 в 20:06
  Массив ([0] = & gt; Массив ([id] = & gt; 1 [name] = & gt; john) [1] = & gt; Массив ([id] = & gt; 2 [name] =  & quot; smith) [2] = & gt; Array ([id] = & gt; 3 [name] = & gt; john) [3] = & gt; Array ([id] = & gt; 4 [name] = & gt; robert)  ) $ temp = array_unique (array_column ($ array, 'name'));  $ unique_arr = array_intersect_key ($ array, $ temp);   

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

2
ответ дан Mauricio Trajano 16 August 2018 в 07:56
поделиться

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

  data = array ([0] = & gt; array ([subject] = & gt; a [object] = & gt; c), [1  ] = & gt; array ([subject] = & gt; b [object] = & gt; d), [2] = & gt; array ([subject] = & gt; d [object] = & gt; b), [3] =  & gt; массив ([subject] = & gt; d [object] = & gt; c), [4] = & gt; array ([subject] = & gt; c [object] = & gt; a), [5] = & gt;  array [[subject] = & gt; c [object] = & gt; d))  

, и вы хотите получить такие массивы:

  data =  array ([0] = & gt; array ([subject] = & gt; a [object] = & gt; c), [1] = & gt; array ([subject] = & gt; b [object] = & gt; d),  [2] = & gt; array ([subject] = & gt; d [object] = & gt; c))  

или

  data = array (  [0] = & gt; array ([subject] = & gt; d [object] = & gt; b), [1] = & gt; array ([subject] = & gt; c [object] = & gt; a), [2  ] = & gt; ([subject] = & gt; c [object] = & gt; d))  

следующий код может помочь

  $ data1  = array ();  $ data1 = $ data;  for ($ q = 0; $ q & lt; count ($ data); $ q ++) {for ($ p = 0; $ p & lt; count ($ data1); $ p ++) {if (($ data [$ q] [  "subject"] == $ data1 [$ p] ["object"]) & amp; & amp; ($ data [$ q] ["object"] == $ data1 [$ p] ["subject"])) {  $ data1 [$ p] ["subject"] = $ data [$ q] ["subject"];  $ data1 [$ p] ["object"] = $ data [$ q] ["object"];  }}} $ data1 = array_values ​​(array_map ("unserialize", array_unique (array_map ("serialize", $ data1))));  $ data = $ data1;   
0
ответ дан milic 16 August 2018 в 07:56
поделиться

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

  function array_unique_multidimensional ($ input) {$ serialized = array_map ('serialize', $ input);  $ unique = array_unique ($ serialized);  return array_intersect_key ($ input, $ unique);  }  
23
ответ дан OIS 16 August 2018 в 07:56
поделиться

Я много думал об этой проблеме и определил, что оптимальное решение должно соответствовать двум правилам.

  1. Для масштабируемости измените массив на месте; никакое копирование в новый массив
  2. Для производительности каждое сравнение должно выполняться только один раз

Учитывая это и учитывая все причуды PHP, ниже приведено решение I придумал. В отличие от некоторых других ответов, он имеет возможность удалять элементы на основе любого ключа (ов), который вы хотите. Ожидается, что входной массив будет числовым.

  $ count_array = count ($ input);  for ($ i = 0; $ i & lt; $ count_array; $ i ++) {if (isset ($ input [$ i])) {для ($ j = $ i + 1; $ j & lt; $ count_array; $ j ++  ) {if (isset ($ input [$ j])) {// это то, где вы делаете свое сравнение для обманов, если ($ input [$ i] ['checksum'] == $ input [$ j] ['checksum  ']) {unset ($ input [$ j]);  }}}}}  

Единственный недостаток заключается в том, что ключи не в порядке, когда итерация завершается. Это не проблема, если впоследствии вы используете только петли foreach, но если вам нужно использовать цикл for, вы можете поместить $ input = array_values ​​($ input); после этого изменить нумерацию ключи.

0
ответ дан Snake 16 August 2018 в 07:56
поделиться

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

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

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

3
ответ дан Wallace Maxters 16 August 2018 в 07:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: