Sort multidimensional array by multiple keys

前端 未结 7 613
挽巷
挽巷 2020-11-22 10:05

I\'m trying to sort a multidimensional array by multiple keys, and I have no idea where to start. I looked at uasort, but wasn\'t quite sure how to write a function for what

7条回答
  •  情歌与酒
    2020-11-22 10:17

    You can do it with usort. The $cmp_function argument could be:

    function my_sorter($a, $b) {
        $c = strcmp($a['state'], $b['state']);
        if($c != 0) {
            return $c;
        }
    
        $c = strcmp($a['event_type'], $b['event_type']);
        if($c != 0) {
            return $c;
        }
    
        return strcmp($a['date_start'], $b['date_start']);
    }
    

    For an arbitrary number of fields in PHP 5.3, you can use closures to create a comparison function:

    function make_cmp($fields, $fieldcmp='strcmp') {
        return function ($a, $b) use (&$fields) {
            foreach ($fields as $field) {
                $diff = $fieldcmp($a[$field], $b[$field]);
                if($diff != 0) {
                    return $diff;
                }
            }
            return 0;
        }
    }
    
    usort($arr, make_cmp(array('state', 'event_type', 'date_start')))
    

    For an arbitrary number of fields of different types in PHP 5.3:

    function make_cmp($fields, $dfltcmp='strcmp') {
        # assign array in case $fields has no elements
        $fieldcmps = array();
        # assign a comparison function to fields that aren't given one
        foreach ($fields as $field => $cmp) {
            if (is_int($field) && ! is_callable($cmp)) {
                $field = $cmp;
                $cmp = $dfltcmp;
            }
            $fieldcmps[$field] = $cmp;
        }
        return function ($a, $b) use (&$fieldcmps) {
            foreach ($fieldcmps as $field => $cmp) {
                $diff = call_user_func($cmp, $a[$field], $b[$field]);
                if($diff != 0) {
                    return $diff;
                }
            }
            return 0;
        }
    }
    
    function numcmp($a, $b) {
        return $a - $b;
    }
    function datecmp($a, $b) {
        return strtotime($a) - strtotime($b);
    }
    /**
     * Higher priority come first; a priority of 2 comes before 1.
     */
    function make_evt_prio_cmp($priorities, $default_priority) {
        return function($a, $b) use (&$priorities) {
            if (isset($priorities[$a])) {
                $prio_a = $priorities[$a];
            } else {
                $prio_a = $default_priority;
            }
            if (isset($priorities[$b])) {
                $prio_b = $priorities[$b];
            } else {
                $prio_b = $default_priority;
            }
            return $prio_b - $prio_a;
        };
    }
    
    $event_priority_cmp = make_evt_prio_cmp(
        array('meeting' => 5, 'party' => 10, 'concert' => 7), 
        0);
    
    usort($arr, make_cmp(array('state', 'event' => $event_priority_cmp, 'date_start' => 'datecmp', 'id' => 'numcmp')))
    

提交回复
热议问题