Array对象数组唯一,具有Object中某些键的exclude选项

时间:2017-03-30 21:30:30

标签: php arrays array-unique

我有一个包含很少字段的Object Array。

我能够使用以下代码获取此对象数组的唯一数组:

$aa = array_unique($dd,SORT_REGULAR);

但我想要实现的是,我想从"唯一检查"中排除对象中的某些键。假设所有对象值都匹配,除了" valid_from"和" valid_to"日期字段。

下面是数组结构:

Array
(
    [9948] => stdClass Object
        (
            [payrate] => 78.00000
            [valid_from] => 03/01/2017
            [valid_to] => 03/31/2017
        )

    [15133] => stdClass Object
        (
            [payrate] => 78.00000
            [valid_from] => 04/01/2017
            [valid_to] => 04/31/2017
        )

)

因此,根据上述情况,因为我的工资率在两个对象中都是相同的,但是由于有效且不同,它仍将被视为不同的条目。

无论如何,我们可以指定排除对象阵列的Array Unique的某些字段。

2 个答案:

答案 0 :(得分:1)

另见array_unique for objects?

如果使用非stdClass对象,可以实现__toString以使用array_unique进行过滤。

要过滤唯一的stdClass,只使用一些属性,您可以尝试以下内容:

从PHP 7开始,您可以使用array_column从stdClass获取值,因此如果您使用PHP7:

array_unique(array_column($array,'payrate'));

在PHP 7之前,您可以尝试:

array_unique(array_map(function($item) {return $item->payrate;},$array);

如果有更多要比较的属性,则有不同的方法。 array_reduce只是其中之一。

这个结果不会有任何重复。因此,如果所有属性都匹配,则会过滤该项目。

$attributes = ['payrate','date']
$filtered = array_reduce($array,function($carry,$item) use ($attributes) {
    if(count(array_filter($attributes,function ($attribute) use ($carry, $item) {
            return !in_array($item->$attribute,array_map(function($carriedItem) use ($attribute) {
                return $carriedItem->$attribute;
            },$carry));
        }))) {
        $carry[] = $item;
    }
    return $carry;
},[]);

请参阅http://sandbox.onlinephpfunctions.com/code/5f8171d76362ada7e165afeaadbecffc6cdd497a

答案 1 :(得分:0)

您可以将array_filter与自定义回调一起使用,以过滤掉数组中的某些元素。

您所要做的就是实现过滤器逻辑。这是一个简单的例子:

<?php
$array = json_decode(
    '[{"name":"foo","count":2},{"name":"foo","count":10},{"name":"baz","count":5},{"name":"foobar","count":10}]'
);

$uniqueCheck = [];

$filtered = array_filter(
    $array,
    function ($element) use (&$uniqueCheck) {
        if (isset($uniqueCheck[$element->name])) {
            return false;
        }

        $uniqueCheck[$element->name] = true;

        return true;
    }
);

print_r($array);
print_r($filtered);

这将产生:

Array
(
    [0] => stdClass Object
        (
            [name] => foo
            [count] => 2
        )

    [1] => stdClass Object
        (
            [name] => foo
            [count] => 10
        )

    [2] => stdClass Object
        (
            [name] => baz
            [count] => 5
        )

    [3] => stdClass Object
        (
            [name] => foobar
            [count] => 10
        )

)

Array
(
    [0] => stdClass Object
        (
            [name] => foo
            [count] => 2
        )

    [2] => stdClass Object
        (
            [name] => baz
            [count] => 5
        )

    [3] => stdClass Object
        (
            [name] => foobar
            [count] => 10
        )

)

修改:将基于$element->count的检查更改为&#34;唯一$element->name检查&#34;。