如何从PHP多维数组中删除重复项,不区分大小写但保留大小写?

时间:2019-05-13 07:52:57

标签: php arrays multidimensional-array

有很多解决方案可以从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 个答案:

答案 0 :(得分:4)

这不是操作数组的内容,而是创建数组的键(与操作主数组的方式类似),然后将键与数据组合(使用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));

答案 1 :(得分:0)

没有内置方法。但是,您可以定义自定义比较器和排序:

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才能使它起作用。

Working example