【问题标题】:Array Unique for Array of Objects with exclude option for certain keys in Object对象数组的唯一数组,对象中某些键的排除选项
【发布时间】:2017-03-30 21:30:29
【问题描述】:

我有一个包含几个字段的对象数组。

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

$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
        )

)

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

我们是否可以为对象数组的唯一数组指定排除某些字段。

【问题讨论】:

    标签: php arrays array-unique


    【解决方案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

    【讨论】:

    • 如果有多个字段,比如工资率,比如说小时,日期等?
    • 是的,我没有测试最后一位。
    • 太棒了,你是个天才,根据我的要求对其进行了调整,它奏效了!
    • 我很乐意提供帮助。我不会经常在一个函数中使用 array_reduce、array_filter 和 array_map ;-)
    • 否则,请检查此场景:sandbox.onlinephpfunctions.com/code/… 看起来像是三个不同的不同值,但由于这两个值都存在于前一个中,因此第三个类不包含在结果中。我认为这是不受欢迎的行为
    【解决方案2】:

    您可以使用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-&gt;count 的检查更改为“唯一$element-&gt;name 检查”。

    【讨论】:

    • 太棒了,让我试试这个,会告诉你的!谢谢!
    • 如果您需要array_filter 的帮助,在我的回答中它链接到 PHP 手册。
    • 这将检查该值是否正确?但是如何从这个回调函数中排除计数?
    猜你喜欢
    • 2020-02-23
    • 2016-09-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 1970-01-01
    • 2017-04-15
    • 2018-09-25
    • 1970-01-01
    相关资源
    最近更新 更多