Domanda

Ciao a tutti, sto cercando di trovare valori x duplicati da questo array, rimuoverli e lasciare solo quelli univoci.Ad esempio il mio array è

Array
(
[0] => Array
    (
        [x] => 0.5
        [y] => 23
    )

[1] => Array
    (
        [x] => 23
        [y] => 21.75
    )

[2] => Array
    (
        [x] => 14.25
        [y] => 21.875
    )

[3] => Array
    (
        [x] => 19.375
        [y] => 21.75
    )

[4] => Array
    (
        [x] => 9.125
        [y] => 21.875
    )

[5] => Array
    (
        [x] => 23
        [y] => 19.625
    )

[6] => Array
    (
        [x] => 19.375
        [y] => 19.625
    ) 
)

Quindi quello che devo fare è scorrere l'intera cosa e vedere il primo valore x come .5, quindi continuare e qualsiasi altra cosa abbia x come .5 rimuoverla dall'array in modo che alla fine ho un array simile a questo

 Array
   (
[0] => Array
    (
        [x] => 0.5
        [y] => 23
    )

[1] => Array
    (
        [x] => 23
        [y] => 21.75
    )

[2] => Array
    (
        [x] => 14.25
        [y] => 21.875
    )

[3] => Array
    (
        [x] => 19.375
        [y] => 21.75
    )

[4] => Array
    (
        [x] => 9.125
        [y] => 21.875
    )
)

dove tutti i valori X sono unici.Ho cercato online e ho trovato questa funzione da utilizzare ma non sembra funzionare:

 $result = array_map("unserialize", array_unique(array_map("serialize", $array)));    
È stato utile?

Soluzione

Solo loop attraverso e trova valori unici mentre vai:

$taken = array();

foreach($items as $key => $item) {
    if(!in_array($item['x'], $taken)) {
        $taken[] = $item['x'];
    } else {
        unset($items[$key]);
    }
}
.

Ogni volta la prima volta che viene utilizzato il valore x, lo salviamo - e gli usi successivi sono unset dall'array.

Altri suggerimenti

array_unique confronta valori di stringa, in modo da poter creare oggetti (con una funzione __toString sovraccaricata) come passaggio intermedio.

class XKeyObj {
    public $x;
    public $y;

    public function XKeyObj($x, $y) {
        $this->x = $x;
        $this->y = $y;
    }

    public function __toString() { return strval($this->x); }
}

function array_to_xKey($arr) { return new XKeyObj($arr['x'], $arr['y']); }
function xKey_to_array($obj) { return array('x' => $obj->x, 'y' => $obj->y); }

$input = array(
    array('x' => 0.5, 'y' => 23),
    array('x' => 23, 'y' => 21.75),
    array('x' => 14.25, 'y' => 21.875),
    array('x' => 19.375, 'y' => 21.75),
    array('x' => 9.125, 'y' => 21.875),
    array('x' => 23, 'y' => 19.625),
    array('x' => 19.375, 'y' => 19.625)
);

$output = array_map('xKey_to_array',
                    array_unique(array_map('array_to_xKey', $input)));

print_r($output);
.

Il risultato:

Array
(
    [0] => Array
        (
            [x] => 0.5
            [y] => 23
        )

    [1] => Array
        (
            [x] => 23
            [y] => 21.75
        )

    [2] => Array
        (
            [x] => 14.25
            [y] => 21.875
        )

    [3] => Array
        (
            [x] => 19.375
            [y] => 21.75
        )

    [4] => Array
        (
            [x] => 9.125
            [y] => 21.875
        )

)
.

Quando si eseguono controlli iterati sugli array, le prestazioni si rallentano in_array() peggiorerà progressivamente man mano che l'array di ricerca temporanea aumenta di dimensioni.

Con questo in mente, utilizzare chiavi associative temporanee per identificare i successivi duplicati in modo che !isset() può essere richiamato sulla variabile di risultato in crescita.Poiché gli array php sono mappe hash, questa tecnica avrà costantemente prestazioni superiori in_array().

C'è un problema con queste chiavi temporanee che si applica specificamente ai valori di tipo float. Quando i float vengono utilizzati come chiavi dell'array, php li convertirà in numeri interi troncandoli ("flooring" non "arrotondamento").Per evitare questo effetto collaterale indesiderato, anteporre un carattere non numerico (diverso da un trattino, ovviamente) ai tasti temporanei in modo che il float diventi una stringa.

Codice:(Dimostrazione)

$array = [
    ['x' => 0.5, 'y' => 23],
    ['x' => 23, 'y' => 21.75],
    ['x' => 14.25, 'y' => 21.875],
    ['x' => 19.375, 'y' => 21.75],
    ['x' => 9.125, 'y' => 21.875], 
    ['x' => 23, 'y' => 19.625],
    ['x' => 19.375, 'y' => 19.625],
];

foreach ($array as $row) {
    if (!isset($result['#' . $row['y']])) {
        $result['#' . $row['y']] = $row;
    }
}
var_export(array_values($result));

Produzione:

array (
  0 => 
  array (
    'x' => 0.5,
    'y' => 23,
  ),
  1 => 
  array (
    'x' => 23,
    'y' => 21.75,
  ),
  2 => 
  array (
    'x' => 14.25,
    'y' => 21.875,
  ),
  3 => 
  array (
    'x' => 23,
    'y' => 19.625,
  ),
)

p.s.Se si tratta di valori stringa o interi come chiavi temporanee, non è necessario anteporre alcun carattere.Se non ti interessa rimuovere le chiavi temporanee dal risultato (perché stai accedendo solo ai valori del sottoarray "down script", non è necessario chiamare array_values() dopo aver ripetuto.

array_unique(my_array, SORT_REGULAR)
.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top