mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
ENHANCEMENT: Made it possible to sort by multiple fields in ArrayList::sort().
This commit is contained in:
parent
462689a4e6
commit
b3fc458101
@ -180,15 +180,35 @@ class ArrayList extends ViewableData implements SS_List {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts this list by one or more fields. You can either pass in a single
|
||||
* field name and direction, or a map of field names to sort directions.
|
||||
*
|
||||
* @param string|array $by
|
||||
* @param string $dir
|
||||
* @see SS_List::sort()
|
||||
*/
|
||||
public function sort($by, $dir = 'ASC') {
|
||||
$sorts = array();
|
||||
$dir = strtoupper($dir) == 'DESC' ? SORT_DESC : SORT_ASC;
|
||||
|
||||
foreach ($this->array as $item) {
|
||||
$sorts[] = $this->extract($item, $by);
|
||||
if (!is_array($by)) {
|
||||
$by = array($by => $dir);
|
||||
}
|
||||
|
||||
array_multisort($sorts, $dir, $this->array);
|
||||
foreach ($by as $field => $dir) {
|
||||
$dir = strtoupper($dir) == 'DESC' ? SORT_DESC : SORT_ASC;
|
||||
$vals = array();
|
||||
|
||||
foreach ($this->array as $item) {
|
||||
$vals[] = $this->extract($item, $field);
|
||||
}
|
||||
|
||||
$sorts[] = $vals;
|
||||
$sorts[] = $dir;
|
||||
}
|
||||
|
||||
$sorts[] = &$this->array;
|
||||
call_user_func_array('array_multisort', $sorts);
|
||||
}
|
||||
|
||||
public function offsetExists($offset) {
|
||||
|
@ -208,6 +208,26 @@ class ArrayListTest extends SapphireTest {
|
||||
));
|
||||
}
|
||||
|
||||
public function testMultiSort() {
|
||||
$list = new ArrayList(array(
|
||||
(object) array('Name'=>'Object1', 'F1'=>1, 'F2'=>2, 'F3'=>3),
|
||||
(object) array('Name'=>'Object2', 'F1'=>2, 'F2'=>1, 'F3'=>4),
|
||||
(object) array('Name'=>'Object3', 'F1'=>5, 'F2'=>2, 'F3'=>2),
|
||||
));
|
||||
|
||||
$list->sort('F3', 'ASC');
|
||||
$this->assertEquals($list->first()->Name, 'Object3', 'Object3 should be first in the list');
|
||||
|
||||
$list->sort('F3', 'DESC');
|
||||
$this->assertEquals($list->first()->Name, 'Object2', 'Object2 should be first in the list');
|
||||
|
||||
$list->sort(array('F2'=>'ASC', 'F1'=>'ASC'));
|
||||
$this->assertEquals($list->last()->Name, 'Object3', 'Object3 should be last in the list');
|
||||
|
||||
$list->sort(array('F2'=>'ASC', 'F1'=>'DESC'));
|
||||
$this->assertEquals($list->last()->Name, 'Object1', 'Object1 should be last in the list');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user