PHP filtra los valores de la matriz y elimina duplicados de la matriz multidimensional
-
20-12-2019 - |
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)));
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)