【问题标题】:Sort an array of objects by deeply nested property selected from an adjacent value通过从相邻值中选择的深度嵌套属性对对象数组进行排序
【发布时间】:2015-09-18 17:47:33
【问题描述】:

我正在调用一个 REST API,它返回一个对象数组。其中一些包含更多包含对象的数组,如:

Array
(
    [0] => stdClass Object
        (
            [OPPORTUNITY_ID] => 7443729
            [CUSTOMFIELDS] => Array
                (
                    [0] => stdClass Object
                        (
                            [CUSTOM_FIELD_ID] => OPPORTUNITY_FIELD_7
                            [FIELD_VALUE] => Zorem
                        )
                    [1] => stdClass Object
                        (
                            [CUSTOM_FIELD_ID] => OPPORTUNITY_FIELD_8
                            [FIELD_VALUE] => Zappem
                        )
                )
        )

    [1] => stdClass Object
        (
            [OPPORTUNITY_ID] => 7401996
            [CUSTOMFIELDS] => Array
                (
                    [0] => stdClass Object
                        (
                            [CUSTOM_FIELD_ID] => OPPORTUNITY_FIELD_7
                            [FIELD_VALUE] => Aorem
                        )
                    [1] => stdClass Object
                        (
                            [CUSTOM_FIELD_ID] => OPPORTUNITY_FIELD_8
                            [FIELD_VALUE] => Arappem
                        )
                )
        )

    // [etc.]

)

我想做的是根据OPPORTUNITY_IDCUSTOM_FIELD_ID / FIELD_VALUE 对数组中的第一级对象进行排序。

作为一种场景,用户会点击链接:“按 OPPORTUNITY_FIELD_7 排序”,数组元素 [1] 将变为 [0],因为“Aorem”的字母值高于“Zorem”。

我已经设法使用usort 对第一级对象进行排序:

function sort_results( $a, $b ) {
    if ($a->OPPORTUNITY_ID == $b->OPPORTUNITY_ID) return 0;
    else if ($a->OPPORTUNITY_ID > $b->OPPORTUNITY_ID) return -1;
    else return 1;
}
usort( $json_opportunities, "sort_results" );

但我不知道如何首先根据 OPPORTUNITY_FIELD_7 等 2 级值进行排序。有什么建议么?我是否需要将所有内容都推入一个数组并以这种方式排序,或者有没有一种方法可以在不先重写数组的情况下进行排序?

【问题讨论】:

    标签: php arrays sorting object


    【解决方案1】:

    我们只需要对usort() 进行更高级的回调。例如,使用OPPORTUNITY_FIELD_7 对数组进行排序会比较这些值:

    • $restArray[0]->CUSTOMFIELDS[0]->FIELD_VALUE
    • $restArray[1]->CUSTOMFIELDS[0]->FIELD_VALUE

    因为OPPORTUNITY_FIELD_7 是与我们用来排序的值在同一个数组中的一个值,而不是它的索引,所以我们需要首先找到它所属的数字索引。这是通过循环 CUSTOMFIELDS 直到我们找到 OPPORTUNITY_FIELD_7 来完成的。

    // callback for usort() using "OPPORTUNITY_FIELD_7"
    function sort_OF7($a, $b) {
    
        // get the index where "OPPORTUNITY_FIELD_7" is stored
        foreach($a->CUSTOMFIELDS as $index => $arr) {
            if($arr->CUSTOM_FIELD_ID == 'OPPORTUNITY_FIELD_7') {
                $ai = $index;
                break;
            }
        }
    
        // again
        foreach($b->CUSTOMFIELDS as $index => $arr) {
            if($arr->CUSTOM_FIELD_ID == 'OPPORTUNITY_FIELD_7') {
                $bi = $index;
                break;
            }
        }
    
        // compare values
        return strcmp(
            $a->CUSTOMFIELDS[$ai]->FIELD_VALUE,
            $b->CUSTOMFIELDS[$bi]->FIELD_VALUE
        );
    }
    

    这假定OPPORTUNITY_FIELD_7 在对象中始终可用。

    我们可以快速测试一下:

    // test
    $main = JSON_decode('[{"OPPORTUNITY_ID":7443729,"CUSTOMFIELDS":[{"CUSTOM_FIELD_ID":"OPPORTUNITY_FIELD_7","FIELD_VALUE":"Zorem"},{"CUSTOM_FIELD_ID":"OPPORTUNITY_FIELD_8","FIELD_VALUE":"Zappem"}]},{"OPPORTUNITY_ID":7401996,"CUSTOMFIELDS":[{"CUSTOM_FIELD_ID":"OPPORTUNITY_FIELD_7","FIELD_VALUE":"Aorem"},{"CUSTOM_FIELD_ID":"OPPORTUNITY_FIELD_8","FIELD_VALUE":"Arappem"}]}]');
    print_r($main);
    usort($main, 'sort_OF7');
    print_r($main);
    

    【讨论】:

      猜你喜欢
      • 2019-01-10
      • 2011-07-01
      • 2022-11-03
      • 1970-01-01
      • 2020-10-30
      • 2021-09-19
      • 1970-01-01
      • 2013-12-03
      相关资源
      最近更新 更多