Come faccio a utilizzare array_unique su un array di array?
-
23-09-2019 - |
Domanda
Ho un array
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
)
)
Come si può vedere il tasto 0 è uguale a 1, 3 e 4.E il tasto 2 è diverso da tutti loro.
Quando si esegue il array_unique funzione su di loro, l'unico a sinistra è
Array (
[0] => Array
(
[0] => 33
[user_id] => 33
[1] => 3
[frame_id] => 3
)
)
Tutte le idee perché array_unique non funziona come dovrebbe?
Soluzione
E 'perché array_unique
confronta elementi utilizzando un confronto tra stringhe. Dal docs :
Nota: Due elementi sono considerati uguali se e solo se (string) $ elem1 === (string) $ elem2. In parole: quando la rappresentazione di stringa è lo stesso. Verrà utilizzato il primo elemento.
La rappresentazione di stringa di un array è semplicemente la parola Array
, non importa ciò che i suoi contenuti sono.
Si può fare quello che si vuole fare utilizzando la seguente:
$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
Ecco come funziona:
-
Ogni elemento dell'array viene serializzato. Questo sarà unico sulla base dell'array contenuti.
-
I risultati di questo sono gestiti attraverso
array_unique
, quindi solo array con unico le firme sono lasciati. -
array_intersect_key
avrà le chiavi dei pezzi unici da mappa / unica funzione (perché le chiavi della matrice origine vengono conservati) e tirare fuori della vostra fonte originale matrice.
Altri suggerimenti
array_unique()
supporta solo gli array multidimensionali in PHP 5.2.9 e superiori.
Al contrario, è possibile creare un hash della matrice e controllare la presenza di unico-ness.
$hashes = array();
foreach($array as $val) {
$hashes[md5(serialize($val))] = $val;
}
array_unique($hashes);
Ecco una versione migliorata del @ di ryeguy risposta :
<?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
In primo luogo, non fa la serializzazione non necessari. In secondo luogo, a volte attributi può essere diverso anche così id è lo stesso.
ho incontrato con Google Places API . Stavo combinare i risultati di diverse richieste con diversi tipi di oggetti (si pensi tag). Ma ho avuto i duplicati, dal momento che un oggetto può essere messo in diverse categorie (tipi). E il metodo con serialize
non ha funzionato, dal momento che i attrs erano diverse, vale a dire, photo_reference
e reference
. Probabilmente questi sono come gli ID temporanei.
array_unique ricorsiva lavoro deosn't, quindi pensa solo "questo sono tutti Array
s, cerchiamo di uccidere tutti tranne uno ... ci siamo!"
Risposta rapida (TL;DR)
- Valori distinti possono essere estratti dal PHP Array di AssociativeArrays utilizzando foreach
- Questo è un approccio semplicistico
Risposta Dettagliata
Contesto
- PHP 5.3
- PHP Array di AssociativeArrays (tabluar dati composito variabile)
- Nome alternativo per questa variabile composita è ArrayOfDictionary (AOD)
Problema
- Scenario: DeveloperMarsher ha un PHP tabulare variabile composita
- DeveloperMarsher desidera estrarre i valori distinti su una specifica coppia nome-valore
- Nell'esempio riportato di seguito, DeveloperMarsher vuole ottenere righe per ogni distinta
fname
coppia nome-valore
Soluzione
example01 ;;DeveloperMarsher inizia con un tabluar variabile di dati che assomiglia a questo
$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": "flintstone" } ]',true);
example01 ;;DeveloperMarsher in grado di estrarre i valori distinti con un ciclo foreach che tracce visto i valori
$sgfield = 'fname'; $bgnocase = true; // $targfield = $sgfield; $ddseen = Array(); $vout = Array(); foreach ($aodtable as $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[] = Array( $rowout ); } } //;; print var_export( $vout, true );
Risultato
array ( 0 => array ( 0 => array ( 'fname' => 'homer', 'lname' => 'simpson', ), ), 1 => array ( 0 => array ( 'fname' => 'bart', 'lname' => 'johnson', ), ), 2 => array ( 0 => array ( 'fname' => 'fred', 'lname' => 'flintstone', ), ), )
Insidie
- Questa soluzione non viene aggregato su campi che non sono parte della DISTINTA
- Arbitrario coppie nome-valore sono tornato da arbitrariamente scelto righe distinte
- Arbitrario ordinamento ordine di uscita
- Arbitraria manipolazione della lettera-case (capitale di Un distinto dalla minuscola ?)
Vedi anche
- php array_intersect_key
- php array_flip
function array_unique_recursive($array)
{
$array = array_unique($array, SORT_REGULAR);
foreach ($array as $key => $elem) {
if (is_array($elem)) {
$array[$key] = array_unique_recursive($elem);
}
}
return $array;
}
Non che fare il trucco?