Как удалить дубликаты из многомерного массива PHP, без учета регистра, но с сохранением регистра? - PullRequest
4 голосов
/ 13 мая 2019

Существует множество решений для удаления дубликатов из многомерных массивов в PHP, но я не нашел такого, который обнаруживает дубликаты независимо от случая, но сохраняет их в выходных данных:

// Sample data
$arr  = [
    ['id' => 1, 'term' => 'Hello'],
    ['id' => 1, 'term' => 'hello'],
    ['id' => 2, 'term' => 'Hello'],
    ['id' => 2, 'term' => 'hello']
];

// Desired output
$arr  = [
    ['id' => 1, 'term' => 'Hello'],
    ['id' => 2, 'term' => 'Hello']
];
// Ex 1. case sensitive, preserves case
$serialized = array_map('serialize', $arr);
$unique = array_unique($serialized);
$unique = array_intersect_key($arr, $unique);
// Ex 2. case insensitive, doesn't preserve case
$unique = array_map('unserialize',
    array_unique(
        array_map('strtolower',
            array_map('serialize',$arr)
        )
    )
);

Ответы [ 2 ]

3 голосов
/ 13 мая 2019

Вместо того, чтобы манипулировать содержимым массива, он создает ключ к массиву (аналогично тому, как вы манипулируете основным массивом), а затем, когда вы комбинируете ключ с данными (используя array_combine()), дубликатыудаляются (поскольку в результате может существовать только 1 ключ) ...

$arr  = [
    ['id' => 1, 'term' => 'Hello'],
    ['id' => 1, 'term' => 'hello'],
    ['id' => 1, 'term' => 'Hello'],
    ['id' => 2, 'term' => 'Hello']
];

$key = array_map("serialize", $arr);
$key = array_map("strtolower", $key);
$new = array_combine($key, $arr);

print_r(array_values($new));

дает ...

Array
(
    [0] => Array
        (
            [id] => 1
            [term] => Hello
        )

    [1] => Array
        (
            [id] => 2
            [term] => Hello
        )

)

Для вертикально поставленных задач его можно заключить в 1 (хотя и менее читабельная) строка ...

$new = array_values(array_combine(array_map("strtolower", array_map("serialize", $arr)), $arr));
0 голосов
/ 13 мая 2019

Там нет встроенного способа. Однако вы можете определить собственный компаратор и сортировку:

function compare($a, $b) {
     ksort($a);
     ksort($b); //To ignore keys not in the same order
     return strtolower(serialize($a)) <=> strtolower(serialize($b));
}

function array_unique_callback($arr, $callback) {
    $copy = $arr;
    usort($copy, $callback);
    $previous = null;
    $arr = [];
    foreach ($copy as $key => $value) {
        if ($previous === null || $callback($previous,$value) !== 0) {
            $previous = $value;
            $arr[$key] = $value;
        }
    }
    return $arr;
}

// Sample data
$arr  = [
    ['id' => 1, 'term' => 'Hello'],
    ['id' => 2, 'term' => 'hello'],
    ['id' => 1, 'term' => 'hello'],
    ['id' => 2, 'term' => 'Hello']
];

print_r(array_unique_callback($arr, 'compare'));

Обратите внимание, что это не будет работать для многомерных подмассивов, если их ключи не находятся в том же порядке. Возможно, вам придется сделать рекурсивный ksort, чтобы заставить это работать.

Рабочий пример

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...