Pregunta

Hola a todos, estoy tratando de encontrar valores x duplicados de esta matriz, eliminarlos y dejar solo los únicos.Por ejemplo mi matriz es

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
    ) 
)

Entonces, lo que necesito que suceda es recorrer todo el proceso y ver el primer valor de x como .5, luego continuar y cualquier otra cosa que tenga x como .5 eliminarlo de la matriz para que al final tenga una matriz que se vea así.

 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
    )
)

donde todos los valores de X son únicos.Busqué en línea y encontré esta función, pero no parece funcionar:

 $result = array_map("unserialize", array_unique(array_map("serialize", $array)));    
¿Fue útil?

Solución

Simplemente recorra y encuentre valores únicos a medida que avanza:

$taken = array();

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

Cada primera vez x Se utiliza el valor, lo guardamos y los usos posteriores se unset de la matriz.

Otros consejos

array_unique compara los valores de cadena, por lo que puede crear objetos (con una función sobrecargada de código __toString) como un paso 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);

El resultado:

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
        )

)

Al realizar comprobaciones iteradas en matrices, el rendimiento disminuye con in_array() empeorará progresivamente a medida que su matriz de búsqueda temporal aumente de tamaño.

Teniendo esto en cuenta, utilice claves asociativas temporales para identificar duplicados posteriores para que !isset() se puede invocar en su variable de resultado creciente.Debido a que las matrices php son mapas hash, esta técnica superará consistentemente in_array().

Hay un problema con estas claves temporales que se aplica específicamente a los valores de tipo flotante. Cuando los flotantes se utilizan como claves de matriz, php los convertirá a números enteros truncando ("piso", no "redondeando").Para evitar este efecto secundario no deseado, anteponga un carácter no numérico (que no sea un guión, por supuesto) a las claves temporales para que el flotante se convierta en una cadena.

Código:(Manifestación)

$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));

Producción:

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,
  ),
)

PD.Si se trata de valores de cadena o enteros como claves temporales, no es necesario anteponer ningún carácter.Si no le importa eliminar las claves temporales del resultado (porque solo está accediendo a los valores del subarreglo "script abajo", entonces no necesita llamar array_values() después de iterar.

array_unique(my_array, SORT_REGULAR)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top