diff --git a/lib/Cake/Test/Case/Utility/Set2Test.php b/lib/Cake/Test/Case/Utility/Set2Test.php index 01dd79e6a..735916fa4 100644 --- a/lib/Cake/Test/Case/Utility/Set2Test.php +++ b/lib/Cake/Test/Case/Utility/Set2Test.php @@ -142,4 +142,83 @@ class Set2Test extends CakeTestCase { $result = Set2::get($data, '1.Article'); $this->assertEquals($data[1]['Article'], $result); } + +/** + * Test dimensions. + * + * @return void + */ + public function testDimensions() { + $result = Set2::dimensions(array()); + $this->assertEquals($result, 0); + + $data = array('one', '2', 'three'); + $result = Set2::dimensions($data); + $this->assertEquals($result, 1); + + $data = array('1' => '1.1', '2', '3'); + $result = Set2::dimensions($data); + $this->assertEquals($result, 1); + + $data = array('1' => array('1.1' => '1.1.1'), '2', '3' => array('3.1' => '3.1.1')); + $result = Set2::dimensions($data); + $this->assertEquals($result, 2); + + $data = array('1' => '1.1', '2', '3' => array('3.1' => '3.1.1')); + $result = Set2::dimensions($data); + $this->assertEquals($result, 1); + + $data = array('1' => array('1.1' => '1.1.1'), '2', '3' => array('3.1' => array('3.1.1' => '3.1.1.1'))); + $result = Set2::dimensions($data); + $this->assertEquals($result, 2); + + } + +/** + * Test maxDimensions + * + * @return void + */ + public function testMaxDimensions() { + $data = array('1' => '1.1', '2', '3' => array('3.1' => '3.1.1')); + $result = Set2::maxDimensions($data); + $this->assertEquals($result, 2); + + $data = array('1' => array('1.1' => '1.1.1'), '2', '3' => array('3.1' => array('3.1.1' => '3.1.1.1'))); + $result = Set2::maxDimensions($data); + $this->assertEquals($result, 3); + + $data = array( + '1' => array('1.1' => '1.1.1'), + array('2' => array('2.1' => array('2.1.1' => '2.1.1.1'))), + '3' => array('3.1' => array('3.1.1' => '3.1.1.1')) + ); + $result = Set2::maxDimensions($data); + $this->assertEquals($result, 4); + + $data = array( + '1' => array('1.1' => '1.1.1'), + array('2' => array('2.1' => array('2.1.1' => array('2.1.1.1')))), + '3' => array('3.1' => array('3.1.1' => '3.1.1.1')) + ); + $result = Set2::maxDimensions($data); + $this->assertEquals($result, 5); + + $data = array( + '1' => array('1.1' => '1.1.1'), + array('2' => array('2.1' => array('2.1.1' => array('2.1.1.1' => '2.1.1.1.1')))), + '3' => array('3.1' => array('3.1.1' => '3.1.1.1')) + ); + $result = Set2::maxDimensions($data); + $this->assertEquals($result, 5); + + $data = array( + '1' => array('1.1' => '1.1.1'), + array('2' => array('2.1' => array('2.1.1' => array('2.1.1.1' => '2.1.1.1.1')))), + '3' => array('3.1' => array('3.1.1' => '3.1.1.1')) + ); + $result = Set2::maxDimensions($data); + $this->assertEquals($result, 5); + } + } diff --git a/lib/Cake/Utility/Set2.php b/lib/Cake/Utility/Set2.php index 1b2453775..17d4a0f17 100644 --- a/lib/Cake/Utility/Set2.php +++ b/lib/Cake/Utility/Set2.php @@ -90,15 +90,57 @@ class Set2 { } +/** + * Counts the dimensions of an array. + * Only considers the dimension of the first element in the array. + * + * If you have an un-even or hetrogenous array, consider using Set2::maxDimensions() + * to get the dimensions of the array. + * + * @param array $array Array to count dimensions on + * @return integer The number of dimensions in $data + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::countDim + */ public static function dimensions(array $data) { - + if (empty($data)) { + return 0; + } + reset($data); + $depth = 1; + while ($elem = array_shift($data)) { + if (is_array($elem)) { + $depth += 1; + $data =& $elem; + } else { + break; + } + } + return $depth; } - /** - * Map a callback across all elements in a set. - * Can be provided a path to only modify slices of the set. - * - */ +/** + * Counts the dimensions of *all* array elements. Useful for finding the maximum + * number of dimensions in a mixed array. + * + * @param array $data Array to count dimensions on + * @return integer The maximum number of dimensions in $data + * @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::countDim + */ + public static function maxDimensions(array $data) { + $depth = array(); + if (is_array($data) && reset($data) !== false) { + foreach ($data as $value) { + $depth[] = Set2::dimensions((array)$value) + 1; + } + } + return max($depth); + } + +/** + * Map a callback across all elements in a set. + * Can be provided a path to only modify slices of the set. + * + */ public static function map(array $data, $path, $function = null) { }