Значения массива PHP-фильтра и удаление дубликатов из многомерного массива
-
20-12-2019 - |
Вопрос
Привет всем, я пытаюсь найти повторяющиеся значения x из этого массива, удалить их и оставить только уникальные.Например, мой массив
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
)
)
Итак, что мне нужно сделать, это пройти через все это и увидеть первое значение x как .5, затем продолжить, а все остальное, что имеет x как .5, удалить его из массива, чтобы в конце у меня был массив, который выглядит так
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
)
)
где все значения X уникальны.Я поискал в Интернете и нашел эту функцию, но она, похоже, не работает:
$result = array_map("unserialize", array_unique(array_map("serialize", $array)));
Решение
Просто петлю через и найду уникальные значения, как вы идете:
$taken = array();
foreach($items as $key => $item) {
if(!in_array($item['x'], $taken)) {
$taken[] = $item['x'];
} else {
unset($items[$key]);
}
}
.
Каждый первый раз, когда используется значение x
, мы сохраняем его - и последующие использование представляют собой unset
из массива.
Другие советы
array_unique
сравнивает строковые значения, поэтому вы можете создавать объекты (с перегруженным __toString
функция) в качестве промежуточного шага.
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);
Результат:
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
)
)
При выполнении итерационных проверках на массивах, сопротивление производительности с in_array()
будет постепенно ухудшаться, поскольку ваш временный массив поиска увеличивается по размеру.
С учетом этого используйте временные ассоциативные клавиши для выявления последующих дубликатов, чтобы !isset()
можно вызвать на вашу переменную результата. Поскольку PHP-массивы являются хэш-карты, эта техника будет последовательно превзойти in_array()
.
код: ( Demo )
$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));
.
Выход:
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. При работе со строковыми или целочисленными значениями в качестве временных ключей нет необходимости представлять какие-либо символы. Если вы не заботитесь о удалении временных ключей из результата (поскольку вы получаете доступ только к значению подложки «Script», то вам не нужно звонить в array_values()
после итерации.
array_unique(my_array, SORT_REGULAR)
.