通过多个键对多维数组进行排序

时间:2021-11-03 10:48:42

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 I need.

我试图用多个键对多维数组进行排序,我不知道从哪里开始。我研究了uasort,但不确定如何写出满足我需要的函数。

I need to sort by the state, then event_type, then date.

我需要按状态排序,然后是event_type,然后是date。

My array looks like this:

我的数组如下所示:

    Array
(
    [0] => Array
        (
            [ID] => 1
            [title] => Boring Meeting
            [date_start] => 2010-07-30
            [time_start] => 06:45:PM
            [time_end] => 
            [state] => new-york
            [event_type] => meeting
        )

    [1] => Array
        (
            [ID] => 2
            [title] => Find My Stapler
            [date_start] => 2010-07-22
            [time_start] => 10:45:AM
            [time_end] => 
            [state] => new-york
            [event_type] => meeting
        )

    [2] => Array
        (
            [ID] => 3
            [title] => Mario Party
            [date_start] => 2010-07-22
            [time_start] => 02:30:PM
            [time_end] => 07:15:PM
            [state] => new-york
            [event_type] => party
        )

    [3] => Array
        (
            [ID] => 4
            [title] => Duct Tape Party
            [date_start] => 2010-07-28
            [time_start] => 01:00:PM
            [time_end] => 
            [state] => california
            [event_type] => party
        )
...... etc

6 个解决方案

#1


139  

You need array_multisort

你需要对

$mylist = array(
    array('ID' => 1, 'title' => 'Boring Meeting', 'event_type' => 'meeting'),
    array('ID' => 2, 'title' => 'Find My Stapler', 'event_type' => 'meeting'),
    array('ID' => 3, 'title' => 'Mario Party', 'event_type' => 'party'),
    array('ID' => 4, 'title' => 'Duct Tape Party', 'event_type' => 'party')
);

# get a list of sort columns and their data to pass to array_multisort
$sort = array();
foreach($mylist as $k=>$v) {
    $sort['title'][$k] = $v['title'];
    $sort['event_type'][$k] = $v['event_type'];
}
# sort by event_type desc and then title asc
array_multisort($sort['event_type'], SORT_DESC, $sort['title'], SORT_ASC,$mylist);

As of PHP 5.5.0:

PHP发送:

array_multisort(array_column($mylist, 'event_type'), SORT_DESC,
                array_column($mylist, 'title'),      SORT_ASC,
                $mylist);

$mylist is now:

mylist美元现在是:

array (
  0 => 
  array (
    'ID' => 4,
    'title' => 'Duct Tape Party',
    'event_type' => 'party',
  ),
  1 => 
  array (
    'ID' => 3,
    'title' => 'Mario Party',
    'event_type' => 'party',
  ),
  2 => 
  array (
    'ID' => 1,
    'title' => 'Boring Meeting',
    'event_type' => 'meeting',
  ),
  3 => 
  array (
    'ID' => 2,
    'title' => 'Find My Stapler',
    'event_type' => 'meeting',
  ),
)

#2


12  

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

你可以用usort。$cmp_function参数可以是:

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:

对于PHP 5.3中任意数量的字段,可以使用闭包创建一个比较函数:

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:

对于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')))

#3


3  

class Sort {
    private $actual_order = 'asc';
    private $actual_field = null;

    public function compare_arrays($array1, $array2) {

        if ($array1[$this->actual_field] == $array2[$this->actual_field]) {
            return 0;
        }
        elseif ($array1[$this->actual_field] > $array2[$this->actual_field]) {
            return ($this->actual_order == 'asc' ? 1 : -1);
        }
        else {
            return ($this->actual_order == 'asc' ? -1 : 1);
        }

    }


    public function order_array(&$array) {

        usort($array, array($this, 'compare_arrays'));

    }


    public function __construct ($field, $actual_order = 'asc') {
        $this->actual_field = $field;
        $this->actual_order = $actual_order;
    }

}

// use

$sort = new Sort ("state");

$sort->order_array($array);

#4


3  

I have tried to below code and i successfully

我已经尝试了下面的代码和我成功。

array code

数组的代码

$songs =  array(
        '1' => array('artist'=>'Smashing Pumpkins', 'songname'=>'Soma'),
        '2' => array('artist'=>'The Decemberists', 'songname'=>'The Island'),
        '3' => array('artist'=>'Fleetwood Mac', 'songname' =>'Second-hand News')
);

call array sorting function

调用数组排序函数

$songs = subval_sort($songs,'artist'); 
print_r($songs);

array sorting funcation

数组排序funcation

function subval_sort($a,$subkey) {
    foreach($a as $k=>$v) {
        $b[$k] = strtolower($v[$subkey]);
    }
    asort($b);
    foreach($b as $key=>$val) {
        $c[] = $a[$key];
    }
    return $c;
}

if array reverse sorting function

如果数组反向排序函数

function subval_sort($a,$subkey) {
        foreach($a as $k=>$v) {
            $b[$k] = strtolower($v[$subkey]);
        }
        arsort($b);
        foreach($b as $key=>$val) {
            $c[] = $a[$key];
        }
        return $c;
    }

#5


1  

Improving on @Stijn Leenknegt's genius code, here is my 2 cent pragmatic function:

改进@Stijn Leenknegt的天才代码,以下是我的2分实用功能:

$data[] = array('volume' => 67, 'edition' => 2);
$data[] = array('volume' => 86, 'edition' => 1);
$data[] = array('volume' => 85, 'edition' => 6);
$data[] = array('volume' => 98, 'edition' => 2);
$data[] = array('volume' => 86, 'edition' => 6);
$data[] = array('volume' => 67, 'edition' => 7);

function make_cmp(array $sortValues)
{
    return function ($a, $b) use (&$sortValues) {
        foreach ($sortValues as $column => $sortDir) {
            $diff = strcmp($a[$column], $b[$column]);
            if ($diff !== 0) {
                if ('asc' === $sortDir) {
                    return $diff;
                }
                return $diff * -1;
            }
        }
        return 0;
    };
}

usort($data, make_cmp(['volume' => "desc", 'edition' => "asc"]));

#6


0  

if you want to sort multi dimentional array

如果你想排序多维数组

first array is :

第一个数组:

$results['total_quote_sales_person_wise']['quote_po'];

second one is :

第二个是:

$results['total_quote_sales_person_wise']['quote_count'];

this both multidimentional array you want to sort descending order at one time then use this code :

这两个多维数组你想要同时按降序排序然后使用这个代码:

array_multisort($results['total_quote_sales_person_wise']['quote_po'],SORT_DESC, $results['total_quote_sales_person_wise']['quote_count'],SORT_DESC);

#1


139  

You need array_multisort

你需要对

$mylist = array(
    array('ID' => 1, 'title' => 'Boring Meeting', 'event_type' => 'meeting'),
    array('ID' => 2, 'title' => 'Find My Stapler', 'event_type' => 'meeting'),
    array('ID' => 3, 'title' => 'Mario Party', 'event_type' => 'party'),
    array('ID' => 4, 'title' => 'Duct Tape Party', 'event_type' => 'party')
);

# get a list of sort columns and their data to pass to array_multisort
$sort = array();
foreach($mylist as $k=>$v) {
    $sort['title'][$k] = $v['title'];
    $sort['event_type'][$k] = $v['event_type'];
}
# sort by event_type desc and then title asc
array_multisort($sort['event_type'], SORT_DESC, $sort['title'], SORT_ASC,$mylist);

As of PHP 5.5.0:

PHP发送:

array_multisort(array_column($mylist, 'event_type'), SORT_DESC,
                array_column($mylist, 'title'),      SORT_ASC,
                $mylist);

$mylist is now:

mylist美元现在是:

array (
  0 => 
  array (
    'ID' => 4,
    'title' => 'Duct Tape Party',
    'event_type' => 'party',
  ),
  1 => 
  array (
    'ID' => 3,
    'title' => 'Mario Party',
    'event_type' => 'party',
  ),
  2 => 
  array (
    'ID' => 1,
    'title' => 'Boring Meeting',
    'event_type' => 'meeting',
  ),
  3 => 
  array (
    'ID' => 2,
    'title' => 'Find My Stapler',
    'event_type' => 'meeting',
  ),
)

#2


12  

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

你可以用usort。$cmp_function参数可以是:

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:

对于PHP 5.3中任意数量的字段,可以使用闭包创建一个比较函数:

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:

对于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')))

#3


3  

class Sort {
    private $actual_order = 'asc';
    private $actual_field = null;

    public function compare_arrays($array1, $array2) {

        if ($array1[$this->actual_field] == $array2[$this->actual_field]) {
            return 0;
        }
        elseif ($array1[$this->actual_field] > $array2[$this->actual_field]) {
            return ($this->actual_order == 'asc' ? 1 : -1);
        }
        else {
            return ($this->actual_order == 'asc' ? -1 : 1);
        }

    }


    public function order_array(&$array) {

        usort($array, array($this, 'compare_arrays'));

    }


    public function __construct ($field, $actual_order = 'asc') {
        $this->actual_field = $field;
        $this->actual_order = $actual_order;
    }

}

// use

$sort = new Sort ("state");

$sort->order_array($array);

#4


3  

I have tried to below code and i successfully

我已经尝试了下面的代码和我成功。

array code

数组的代码

$songs =  array(
        '1' => array('artist'=>'Smashing Pumpkins', 'songname'=>'Soma'),
        '2' => array('artist'=>'The Decemberists', 'songname'=>'The Island'),
        '3' => array('artist'=>'Fleetwood Mac', 'songname' =>'Second-hand News')
);

call array sorting function

调用数组排序函数

$songs = subval_sort($songs,'artist'); 
print_r($songs);

array sorting funcation

数组排序funcation

function subval_sort($a,$subkey) {
    foreach($a as $k=>$v) {
        $b[$k] = strtolower($v[$subkey]);
    }
    asort($b);
    foreach($b as $key=>$val) {
        $c[] = $a[$key];
    }
    return $c;
}

if array reverse sorting function

如果数组反向排序函数

function subval_sort($a,$subkey) {
        foreach($a as $k=>$v) {
            $b[$k] = strtolower($v[$subkey]);
        }
        arsort($b);
        foreach($b as $key=>$val) {
            $c[] = $a[$key];
        }
        return $c;
    }

#5


1  

Improving on @Stijn Leenknegt's genius code, here is my 2 cent pragmatic function:

改进@Stijn Leenknegt的天才代码,以下是我的2分实用功能:

$data[] = array('volume' => 67, 'edition' => 2);
$data[] = array('volume' => 86, 'edition' => 1);
$data[] = array('volume' => 85, 'edition' => 6);
$data[] = array('volume' => 98, 'edition' => 2);
$data[] = array('volume' => 86, 'edition' => 6);
$data[] = array('volume' => 67, 'edition' => 7);

function make_cmp(array $sortValues)
{
    return function ($a, $b) use (&$sortValues) {
        foreach ($sortValues as $column => $sortDir) {
            $diff = strcmp($a[$column], $b[$column]);
            if ($diff !== 0) {
                if ('asc' === $sortDir) {
                    return $diff;
                }
                return $diff * -1;
            }
        }
        return 0;
    };
}

usort($data, make_cmp(['volume' => "desc", 'edition' => "asc"]));

#6


0  

if you want to sort multi dimentional array

如果你想排序多维数组

first array is :

第一个数组:

$results['total_quote_sales_person_wise']['quote_po'];

second one is :

第二个是:

$results['total_quote_sales_person_wise']['quote_count'];

this both multidimentional array you want to sort descending order at one time then use this code :

这两个多维数组你想要同时按降序排序然后使用这个代码:

array_multisort($results['total_quote_sales_person_wise']['quote_po'],SORT_DESC, $results['total_quote_sales_person_wise']['quote_count'],SORT_DESC);