У меня есть массив
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',
),
),
)