Permalink
Browse files

FEATURE: Added GroupedList for grouping lists into sub-lists by commo…

…n values of a field.
  • Loading branch information...
1 parent 565e2ab commit 5242ed1051efac07f35796d5ccc9c6af5c74e7ca @ajshort ajshort committed Dec 26, 2011
Showing with 102 additions and 0 deletions.
  1. +50 −0 model/GroupedList.php
  2. +52 −0 tests/model/GroupedListTest.php
View
@@ -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;
+ }
+
+}
@@ -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);
+ }
+
+}

0 comments on commit 5242ed1

Please sign in to comment.