Значения массива PHP-фильтра и удаление дубликатов из многомерного массива

StackOverflow https://stackoverflow.com//questions/22001121

Вопрос

Привет всем, я пытаюсь найти повторяющиеся значения 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().

есть GOTCHA с этими временными ключами, которые применяются специально для ваших значений типа Float. "). Чтобы избежать этого нежелательного побочного эффекта, добавьте неминовой символ (кроме дефиса, конечно) на временные ключи, чтобы поплавок становиться строкой.

код: ( 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)
.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top