通过从相邻值中选择的深层嵌套属性对对象数组进行排序

时间:2015-09-18 17:47:33

标签: php arrays sorting object

我正在调用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级值进行排序。有什么建议?我是否需要将所有内容都推入数组并按此方式排序,或者有没有一种方法可以在不重写数组的情况下进行排序?

1 个答案:

答案 0 :(得分:2)

我们只需要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);