Merge pull request #148 from ajshort/pull-2

Added GroupedList
This commit is contained in:
Sam Minnée 2012-01-06 16:19:20 -08:00
commit 9a1644f9e1
2 changed files with 102 additions and 0 deletions

50
model/GroupedList.php Normal file
View File

@ -0,0 +1,50 @@
<?php
/**
* A list decorator that allows a list to be grouped into sub-lists by common
* values of a field.
*
* @package sapphire
* @subpackage model
*/
class GroupedList extends SS_ListDecorator {
/**
* @param string $index
* @return ArrayList
*/
public function groupBy($index) {
$result = array();
foreach ($this->list as $item) {
$key = is_object($item) ? $item->$index : $item[$index];
if (array_key_exists($key, $result)) {
$result[$key]->push($item);
} else {
$result[$key] = new ArrayList(array($item));
}
}
return $result;
}
/**
* @param string $index
* @param string $children
* @return ArrayList
*/
public function GroupedBy($index, $children = 'Children') {
$grouped = $this->groupBy($index);
$result = new ArrayList();
foreach ($grouped as $indVal => $list) {
$result->push(new ArrayData(array(
$index => $indVal,
$children => $list
)));
}
return $result;
}
}

View File

@ -0,0 +1,52 @@
<?php
/**
* Tests for the {@link GroupedList} list decorator.
*
* @package sapphire
* @subpackage tests
*/
class GroupedListTest extends SapphireTest {
public function testGroupBy() {
$list = new GroupedList(new ArrayList(array(
array('Name' => 'AAA'),
array('Name' => 'AAA'),
array('Name' => 'BBB'),
array('Name' => 'BBB'),
array('Name' => 'AAA'),
array('Name' => 'BBB'),
array('Name' => 'CCC'),
array('Name' => 'CCC')
)));
$grouped = $list->groupBy('Name');
$this->assertEquals(3, count($grouped));
$this->assertEquals(3, count($grouped['AAA']));
$this->assertEquals(3, count($grouped['BBB']));
$this->assertEquals(2, count($grouped['CCC']));
}
public function testGroupedBy() {
$list = new GroupedList(new ArrayList(array(
array('Name' => 'AAA'),
array('Name' => 'AAA'),
array('Name' => 'BBB'),
array('Name' => 'BBB'),
array('Name' => 'AAA'),
array('Name' => 'BBB'),
array('Name' => 'CCC'),
array('Name' => 'CCC')
)));
$grouped = $list->GroupedBy('Name');
$first = $grouped->first();
$last = $grouped->last();
$this->assertEquals(3, count($first->Children));
$this->assertEquals('AAA', $first->Name);
$this->assertEquals(2, count($last->Children));
$this->assertEquals('CCC', $last->Name);
}
}