У меня есть массив
Array( [0] => Array ( [0] => 33 [user_id] => 33 [1] => 3 [frame_id] => 3 ) [1] => Array ( [0] => 33 [user_id] => 33 [1] => 3 [frame_id] => 3 ) [2] => Array ( [0] => 33 [user_id] => 33 [1] => 8 [frame_id] => 8 ) [3] => Array ( [0] => 33 [user_id] => 33 [1] => 3 [frame_id] => 3 ) [4] => Array ( [0] => 33 [user_id] => 33 [1] => 3 [frame_id] => 3 )
)
Как видите, клавиша 0 такая же, как 1,3 и 4. И ключ 2 отличается от всех.
При запуске функции array_unique на них, только слева
Array ( [0] => Array ( [0] => 33 [user_id] => 33 [1] => 3 [frame_id] => 3 )
)
любые идеи, почему array_unique работает не так, как ожидалось?
Это потому, что array_unique
сравнивает элементы, используя сравнение строк. Из документов :
Примечание. Два элемента считаются равными тогда и только тогда, когда (строка) $ elem1 === (string) $ elem2. В словах: когда строковое представление одно и то же. Будет использоваться первый элемент.
Строковое представление массива – это просто слово Array
, независимо от его содержимого.
Вы можете делать то, что хотите, используя следующее:
$arr = array( array('user_id' => 33, 'frame_id' => 3), array('user_id' => 33, 'frame_id' => 3), array('user_id' => 33, 'frame_id' => 8) ); $arr = array_intersect_key($arr, array_unique(array_map('serialize', $arr))); //result: array 0 => array 'user_id' => int 33 'user' => int 3 2 => array 'user_id' => int 33 'user' => int 8
Вот как это работает:
Каждый элемент массива сериализуется. Это будет уникально на основе содержимого массива.
Результаты этого запускаются через array_unique
, поэтому остаются только массивы с уникальными сигнатурами.
array_intersect_key
возьмет ключи уникальных элементов из карты / уникальной функции (поскольку ключи исходного массива сохранены) и вытащите их из исходного исходного массива.
array_unique()
поддерживает только многомерные массивы в PHP 5.2.9 и выше.
Вместо этого вы можете создать хэш массива и проверить его на уникальность.
$hashes = array(); foreach($array as $val) { $hashes[md5(serialize($val))] = $val; } array_unique($hashes);
Вот улучшенная версия ответа @ ryeguy :
<?php $arr = array( array('user_id' => 33, 'tmp_id' => 3), array('user_id' => 33, 'tmp_id' => 4), array('user_id' => 33, 'tmp_id' => 5) ); # $arr = array_intersect_key($arr, array_unique(array_map('serialize', $arr))); $arr = array_intersect_key($arr, array_unique(array_map(function ($el) { return $el['user_id']; }, $arr))); //result: array 0 => array 'user_id' => int 33 'tmp_id' => int 3
Во-первых, это не делает ненужной сериализации. Во-вторых, иногда атрибуты могут быть разными, поэтому id одинаковый.
Я столкнулся с этим с API Google Адресов . Я сочетал результаты нескольких запросов с разными типами объектов (думаю теги). Но у меня есть дубликаты, так как объект может быть помещен в несколько категорий (типов). И метод с serialize
не работал, поскольку attrs были разными, а именно: photo_reference
и reference
. Вероятно, это похоже на временные идентификаторы.
array_unique deosn't работает рекурсивно, поэтому он просто думает: «Это все Array
, давайте убьем всех, кроме одного … здесь мы идем!»
fname
example01 ;; DeveloperMarsher начинается с переменной данных табуляции, которая выглядит так:
$ aodtable = json_decode ('[ { "fname": "homer" , "lname": "simpson" }, { "fname": "homer" , "lname": "jackson" }, { "fname": "homer" , "lname": "johnson" }, { "fname": "bart" , "lname": "johnson" }, { "fname": "bart" , "lname": "jackson" }, { "fname": "bart" , "lname": "simpson" }, { "fname": "fred" , "lname": "кремневый камень" } ]',правда);
example01 ;; DeveloperMarsher может извлекать отдельные значения с помощью цикла foreach, который отслеживает видимые значения
$ sgfield = 'fname'; $ bgnocase = true; // $ targfield = $ sgfield; $ ddseen = Array (); $ vout = Array (); foreach ($ aodtable как $ datarow) { if ((boolean) $ bgnocase == true) {@ $ datarow [$ targfield] = @strtolower ($ datarow [$ targfield]); } if ((string) @ $ ddseen [$ datarow [$ targfield]] == '') { $ rowout = array_intersect_key ($ datarow, array_flip (array_keys ($ datarow))); $ ddseen [$ datarow [$ targfield]] = $ datarow [$ targfield]; $ vout [] = Массив ($ rowout); } } // ;; print var_export ($ vout, true);
массив ( 0 => массив ( 0 => массив ( 'fname' => 'homer', 'lname' => 'simpson', ), ), 1 => массив ( 0 => массив ( 'fname' => 'bart', 'lname' => 'johnson', ), ), 2 => массив ( 0 => массив ( 'fname' => 'fred', 'lname' => 'flintstone', ), ), )