Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

initial refactoring \util\Set

  • Loading branch information...
commit 9084d697e2658cf760ec4b5d91bb10c7c8778fca 1 parent f7a9ba6
@gwoo gwoo authored nateabele committed
Showing with 475 additions and 657 deletions.
  1. +44 −203 libraries/lithium/tests/cases/util/SetTest.php
  2. +431 −454 libraries/lithium/util/Set.php
View
247 libraries/lithium/tests/cases/util/SetTest.php
@@ -12,22 +12,12 @@
class SetTest extends \lithium\test\Unit {
- /**
- * testDepthWithEmptyData method
- *
- * @return void
- */
public function testDepthWithEmptyData() {
$data = array();
$result = Set::depth($data);
$this->assertEqual($result, 0);
}
- /**
- * testDepthOneLevelWithDefaults method
- *
- * @return void
- */
public function testDepthOneLevelWithDefaults() {
$data = array();
$result = Set::depth($data);
@@ -46,11 +36,6 @@ public function testDepthOneLevelWithDefaults() {
$this->assertEqual($result, 1);
}
- /**
- * testDepthTwoLevelsWithDefaults method
- *
- * @return void
- */
public function testDepthTwoLevelsWithDefaults() {
$data = array('1' => array('1.1' => '1.1.1'), '2', '3' => array('3.1' => '3.1.1'));
$result = Set::depth($data);
@@ -72,22 +57,14 @@ public function testDepthTwoLevelsWithDefaults() {
$result = Set::depth($data, false, 0);
$this->assertEqual($result, 2);
}
- /**
- * testDepthTwoLevelsWithDefaults method
- *
- * @return void
- */
+
public function testDepthTwoLevelsWithAll() {
$data = array('1' => '1.1', '2', '3' => array('3.1' => '3.1.1'));
$result = Set::depth($data, true);
$this->assertEqual($result, 2);
}
- /**
- * testDepthThreeLevelsWithAll method
- *
- * @return void
- */
+
public function testDepthThreeLevelsWithAll() {
$data = array(
'1' => array('1.1' => '1.1.1'), '2', '3' => array('3.1' => array('3.1.1' => '3.1.1.1'))
@@ -119,11 +96,6 @@ public function testDepthThreeLevelsWithAll() {
$this->assertEqual($result, 5);
}
- /**
- * testDepthFourLevelsWithAll method
- *
- * @return void
- */
public function testDepthFourLevelsWithAll() {
$data = array('1' => array('1.1' => '1.1.1'), array(
'2' => array('2.1' => array('2.1.1' => '2.1.1.1'))),
@@ -133,11 +105,6 @@ public function testDepthFourLevelsWithAll() {
$this->assertEqual($result, 4);
}
- /**
- * testDepthFiveLevelsWithAll method
- *
- * @return void
- */
public function testDepthFiveLevelsWithAll() {
$data = array('1' => array('1.1' => '1.1.1'), array(
@@ -155,11 +122,6 @@ public function testDepthFiveLevelsWithAll() {
$this->assertEqual($result, 5);
}
- /**
- * testFlattenOneLevel
- *
- * @return void
- */
public function testFlattenOneLevel() {
$data = array('Larry', 'Curly', 'Moe');
$result = Set::flatten($data);
@@ -170,11 +132,6 @@ public function testFlattenOneLevel() {
$this->assertEqual($result, $data);
}
- /**
- * testFlattenTwoLevels
- *
- * @return void
- */
public function testFlattenTwoLevels() {
$data = array(
array(
@@ -207,11 +164,6 @@ public function testFlattenTwoLevels() {
$this->assertEqual($expected, $result);
}
- /**
- * testFormatmethod
- *
- * @return void
- */
public function testFormat() {
$data = array(
array('Person' => array(
@@ -274,11 +226,6 @@ public function testFormat() {
$this->assertEqual($expected, $result);
}
- /**
- * testMatches first, because extract and others depend on it.
- *
- * @return void
- */
public function testMatchesBasic() {
$a = array(
array('Article' => array('id' => 1, 'title' => 'Article 1')),
@@ -306,11 +253,7 @@ public function testMatchesBasic() {
$this->assertFalse(Set::matches('/Article[id=4]', $a));
$this->assertTrue(Set::matches(array(), $a));
}
- /**
- * testDeeperMatches method
- *
- * @return void
- */
+
public function testMatchesMultipleLevels() {
$result = array(
'Attachment' => array(
@@ -334,12 +277,7 @@ public function testMatchesMultipleLevels() {
$this->assertFalse($result);
}
- /**
- * testSetExtractReturnsEmptyArray method
- *
- * @return void
- */
- public function testSetExtractReturnsEmptyArray() {
+ public function testExtractReturnsEmptyArray() {
$expected = array();
$result = Set::extract(array(), '/Post/id');
$this->assertIdentical($expected, $result);
@@ -357,11 +295,6 @@ public function testSetExtractReturnsEmptyArray() {
$this->assertIdentical($expected, $result);
}
- /**
- * testNumericKeyExtraction method
- *
- * @return void
- */
public function testExtractionOfNotNull() {
$data = array(
'plugin' => null, 'admin' => false, 'controller' => 'posts',
@@ -373,12 +306,7 @@ public function testExtractionOfNotNull() {
$this->assertIdentical($expected, $result);
}
- /**
- * testNumericKeyExtraction method
- *
- * @return void
- */
- public function testNumericKeyExtraction() {
+ public function testExtractOfNumericKeys() {
$data = array(1, 'whatever');
$expected = array(1, 'whatever');
@@ -386,11 +314,6 @@ public function testNumericKeyExtraction() {
$this->assertIdentical($expected, $result);
}
- /**
- * testExtract method
- *
- * @return void
- */
public function testExtract() {
$a = array(
array(
@@ -863,12 +786,7 @@ public function testExtractWithTypeCondition() {
}
- /**
- * testNumericArrayCheck method
- *
- * @return void
- */
- public function testNumericArrayCheck() {
+ public function testIsNumericArrayCheck() {
$data = array('one');
$this->assertTrue(Set::isNumeric(array_keys($data)));
@@ -900,12 +818,7 @@ public function testNumericArrayCheck() {
$this->assertFalse(Set::isNumeric(array_keys($data)));
}
- /**
- * testKeyCheck method
- *
- * @return void
- */
- public function testKeyCheck() {
+ public function testCheckKeys() {
$data = array('Multi' => array('dimensonal' => array('array')));
$this->assertTrue(Set::check($data, 'Multi.dimensonal'));
$this->assertFalse(Set::check($data, 'Multi.dimensonal.array'));
@@ -971,11 +884,6 @@ public function testKeyCheck() {
$this->assertFalse(Set::check($data, '0.Article.user_id.a'));
}
- /**
- * testMerge method
- *
- * @return void
- */
public function testMerge() {
$result = Set::merge(array('foo'));
$this->assertIdentical($result, array('foo'));
@@ -1071,12 +979,6 @@ public function testMerge() {
$this->assertIdentical(Set::normalize(Set::merge($a, $b)), $expected);
}
-
- /**
- * testSort depends on extract
- *
- * @return void
- */
public function testSort() {
$a = array(
array('Person' => array('name' => 'Jeff'), 'Friend' => array(array('name' => 'Nate'))),
@@ -1134,11 +1036,6 @@ public function testSort() {
$this->assertIdentical($a, $b);
}
- /**
- * testInsert method
- *
- * @return void
- */
public function testInsert() {
$a = array('pages' => array('name' => 'page'));
@@ -1163,11 +1060,6 @@ public function testInsert() {
$this->assertIdentical($expected, $result);
}
- /**
- * testRemove method
- *
- * @return void
- */
public function testRemove() {
$a = array('pages' => array('name' => 'page'), 'files' => array('name' => 'files'));
@@ -1191,11 +1083,6 @@ public function testRemove() {
$this->assertIdentical($expected, $result);
}
- /**
- * testCheck method
- *
- * @return void
- */
public function testCheck() {
$set = array(
'My Index 1' => array('First' => 'The first item')
@@ -1213,12 +1100,7 @@ public function testCheck() {
$this->assertFalse(Set::check($set, 'My Index 1.First.Seconds.Third.Fourth'));
}
- /**
- * testWritingWithFunkyKeys method
- *
- * @return void
- */
- public function testWritingWithFunkyKeys() {
+ public function testInsertAndRemoveWithFunkyKeys() {
$set = Set::insert(array(), 'Session Test', "test");
$result = Set::extract($set, '/Session Test');
$this->assertEqual($result, array('test'));
@@ -1230,11 +1112,6 @@ public function testWritingWithFunkyKeys() {
$this->assertTrue(Set::check($set, 'Session Test.Test Case'));
}
- /**
- * testDiff method
- *
- * @return void
- */
public function testDiff() {
$a = array(array('name' => 'main'), array('name' => 'about'));
$b = array(array('name' => 'main'), array('name' => 'about'), array('name' => 'contact'));
@@ -1258,11 +1135,6 @@ public function testDiff() {
$this->assertIdentical($expected, $result);
}
- /**
- * testContains method
- *
- * @return void
- */
public function testContains() {
$a = array(
0 => array('name' => 'main'),
@@ -1279,11 +1151,7 @@ public function testContains() {
$this->assertFalse(Set::contains($a, $b));
$this->assertTrue(Set::contains($b, $a));
}
- /**
- * testCombine method
- *
- * @return void
- */
+
public function testCombine() {
$result = Set::combine(array(), '/User/id', '/User/Data');
$this->assertFalse($result);
@@ -1415,16 +1283,12 @@ public function testCombine() {
$expected = array(2 => null, 14 => null, 25 => null);
$this->assertIdentical($expected, $result);
}
- /**
- * testMapReverse method
- *
- * @return void
- */
+
public function testMapReverse() {
- $result = Set::reverse(null);
+ $result = Set::toArray(null);
$this->assertEqual($result, null);
- $result = Set::reverse(false);
+ $result = Set::toArray(false);
$this->assertEqual($result, false);
$expected = array(
@@ -1476,11 +1340,11 @@ public function testMapReverse() {
)
)
);
- $map = Set::map($expected, true);
+ $map = Set::toObject($expected, true);
$this->assertEqual($map->Array1->Array1Data1, $expected['Array1']['Array1Data1']);
$this->assertEqual($map->Array2[0]->Array2Data1, $expected['Array2'][0]['Array2Data1']);
- $result = Set::reverse($map);
+ $result = Set::toArray($map);
$this->assertEqual($expected, $result);
$expected = array(
@@ -1494,7 +1358,7 @@ public function testMapReverse() {
array('id'=> 2, 'title' => 'Second Tag')
),
);
- $map = Set::map($expected);
+ $map = Set::toObject($expected);
$this->assertIdentical($map->title, $expected['Post']['title']);
foreach ($map->Comment as $comment) {
$ids[] = $comment->id;
@@ -1556,8 +1420,8 @@ public function testMapReverse() {
)
)
);
- $map = Set::map($expected, true);
- $result = Set::reverse($map);
+ $map = Set::toObject($expected, true);
+ $result = Set::toArray($map);
$this->assertIdentical($expected, $result);
$expected = array(
@@ -1621,13 +1485,13 @@ public function testMapReverse() {
'another3' => 'string',
'some3' => 'thing else'
);
- $map = Set::map($expected, true);
- $result = Set::reverse($map);
+ $map = Set::toObject($expected, true);
+ $result = Set::toArray($map);
$this->assertIdentical($expected, $result);
$expected = array('User' => array('psword'=> 'whatever', 'Icon' => array('id' => 851)));
- $map = Set::map($expected);
- $result = Set::reverse($map);
+ $map = Set::toObject($expected);
+ $result = Set::toArray($map);
$this->assertIdentical($expected, $result);
$expected = array('User' => array('psword'=> 'whatever', 'Icon' => array('id' => 851)));
@@ -1636,7 +1500,7 @@ public function testMapReverse() {
$class->User->psword = 'whatever';
$class->User->Icon = new \stdClass;
$class->User->Icon->id = 851;
- $result = Set::reverse($class);
+ $result = Set::toArray($class);
$this->assertIdentical($expected, $result);
$expected = array(
@@ -1654,7 +1518,7 @@ public function testMapReverse() {
$class->User->Profile->name = 'Some Name';
$class->User->Profile->address = 'Some Address';
- $result = Set::reverse($class);
+ $result = Set::toArray($class);
$this->assertIdentical($expected, $result);
$expected = array('User' => array(
@@ -1701,7 +1565,7 @@ public function testMapReverse() {
$class->User->Comment->{'1'}->created = '2007-03-18 10:47:23';
$class->User->Comment->{'1'}->updated = '2007-03-18 10:49:31';
- $result = Set::reverse($class);
+ $result = Set::toArray($class);
$this->assertIdentical($expected, $result);
$expected = array('User' => array(
@@ -1748,7 +1612,7 @@ public function testMapReverse() {
$comment2->created = '2007-03-18 10:47:23';
$comment2->updated = '2007-03-18 10:49:31';
$class->User->Comment = array($comment, $comment2);
- $result = Set::reverse($class);
+ $result = Set::toArray($class);
$this->assertIdentical($expected, $result);
$class = new \stdClass;
@@ -1758,7 +1622,7 @@ public function testMapReverse() {
$class->Profile = new \stdClass;
$class->Profile->name = 'Joe Mamma';
- $result = Set::reverse($class);
+ $result = Set::toArray($class);
$expected = array(
'User' => array('id' => '100'),
'someString' => 'this is some string',
@@ -1774,7 +1638,7 @@ public function testMapReverse() {
$class->Profile->name = 'Joe Mamma';
$class->Profile->_name_ = 'Profile';
- $result = Set::reverse($class);
+ $result = Set::toArray($class);
$expected = array(
'User' => array('id' => '100'),
'Profile' => array('name' => 'Joe Mamma')
@@ -1782,11 +1646,6 @@ public function testMapReverse() {
$this->assertEqual($expected, $result);
}
- /**
- * testMapNesting method
- *
- * @return void
- */
public function testMapNesting() {
$expected = array(
array(
@@ -1845,7 +1704,7 @@ public function testMapNesting() {
)
);
- $mapped = Set::map($expected);
+ $mapped = Set::toObject($expected);
$ids = array();
foreach ($mapped as $object) {
@@ -1857,7 +1716,7 @@ public function testMapNesting() {
$expected[0]['IndexedPage']['headers']
);
- $result = Set::reverse($mapped);
+ $result = Set::toArray($mapped);
$this->assertIdentical($expected, $result);
$data = array(
@@ -1884,7 +1743,7 @@ public function testMapNesting() {
),
)
);
- $mapped = Set::map($data);
+ $mapped = Set::toObject($data);
$expected = new \stdClass();
$expected->_name_ = 'IndexedPage';
@@ -1904,17 +1763,13 @@ public function testMapNesting() {
}
$this->assertEqual($ids, array(1, 2));
- $result = Set::map(null);
+ $result = Set::toObject(null);
$expected = null;
$this->assertEqual($expected, $result);
}
- /**
- * testNestedMappedData method
- *
- * @return void
- */
+
public function testNestedMappedData() {
- $result = Set::map(array(
+ $result = Set::toObject(array(
array(
'Post' => array(
'id' => '1', 'author_id' => '1', 'title' => 'First Post',
@@ -1991,7 +1846,7 @@ public function testNestedMappedData() {
$this->assertEqual($test, $result);
- $result = Set::map(
+ $result = Set::toObject(
array(
'Post' => array(
'id' => '1', 'author_id' => '1', 'title' => 'First Post',
@@ -2063,7 +1918,7 @@ public function testNestedMappedData() {
)
);
- $result = Set::map($data);
+ $result = Set::toObject($data);
$expected = new \stdClass();
$expected->_name_ = 'User';
@@ -2148,7 +2003,7 @@ public function testNestedMappedData() {
)
);
- $result = Set::map($data);
+ $result = Set::toObject($data);
$expected = new \stdClass();
$expected->_name_ = 'FooUser';
@@ -2187,12 +2042,8 @@ public function testNestedMappedData() {
$this->assertEqual($expected, $result);
}
- /**
- * testPushDiff method
- *
- * @return void
- */
- public function testPushDiff() {
+
+ public function testBlend() {
$array1 = array('ModelOne' => array(
'id' => 1001, 'field_one' => 'a1.m1.f1', 'field_two' => 'a1.m1.f2'
));
@@ -2200,7 +2051,7 @@ public function testPushDiff() {
'id' => 1002, 'field_one' => 'a2.m2.f1', 'field_two' => 'a2.m2.f2'
));
- $result = Set::pushDiff($array1, $array2);
+ $result = Set::blend($array1, $array2);
$this->assertIdentical($result, $array1 + $array2);
@@ -2208,7 +2059,7 @@ public function testPushDiff() {
'id' => 1003, 'field_one' => 'a3.m1.f1',
'field_two' => 'a3.m1.f2', 'field_three' => 'a3.m1.f3'
));
- $result = Set::pushDiff($array1, $array3);
+ $result = Set::blend($array1, $array3);
$expected = array('ModelOne' => array(
'id' => 1001, 'field_one' => 'a1.m1.f1',
@@ -2234,14 +2085,14 @@ public function testPushDiff() {
))
);
- $result = Set::pushDiff($array1, $array2);
+ $result = Set::blend($array1, $array2);
$this->assertIdentical($result, $array1);
$array3 = array(array('ModelThree' => array(
'id' => 1003, 'field_one' => 's3.0.m3.f1', 'field_two' => 's3.0.m3.f2'
)));
- $result = Set::pushDiff($array1, $array3);
+ $result = Set::blend($array1, $array3);
$expected = array(
array(
'ModelOne' => array(
@@ -2257,28 +2108,18 @@ public function testPushDiff() {
);
$this->assertIdentical($expected, $result);
- $result = Set::pushDiff($array1, null);
+ $result = Set::blend($array1, null);
$this->assertIdentical($result, $array1);
- $result = Set::pushDiff($array1, $array2);
+ $result = Set::blend($array1, $array2);
$this->assertIdentical($result, $array1 + $array2);
}
- /**
- * testStrictKeyCheck method
- *
- * @return void
- */
public function testStrictKeyCheck() {
$set = array('a' => 'hi');
$this->assertFalse(Set::check($set, 'a.b'));
}
- /**
- * Tests list normalization where the input array's keys are mixed between strings and integers.
- *
- * @return void
- */
public function testMixedKeyNormalization() {
$input = array('"string"' => array('before' => '=>'), 1 => array('before' => '=>'));
$result = Set::normalize($input);
View
885 libraries/lithium/util/Set.php
@@ -30,6 +30,29 @@
class Set {
/**
+ * Add the keys/values in `$array2` that are not found in `$array` onto the end of `$array`.
+ *
+ * @param mixed $array Original array.
+ * @param mixed $array2 Second array to add onto the Original.
+ * @return array A Blended array of keys and values.
+ */
+ public static function blend($array, $array2) {
+ if (empty($array) && !empty($array2)) {
+ return $array2;
+ }
+ if (!empty($array) && !empty($array2)) {
+ foreach ($array2 as $key => $value) {
+ if (!isset($array[$key])) {
+ $array[$key] = $value;
+ } elseif (is_array($value)) {
+ $array[$key] = static::blend($array[$key], $array2[$key]);
+ }
+ }
+ }
+ return $array;
+ }
+
+ /**
* Checks if a particular path is set in an array
*
* @param mixed $data Data to check on.
@@ -43,7 +66,6 @@ public static function check($data, $path = null) {
if (!is_array($path)) {
$path = explode('.', $path);
}
-
foreach ($path as $i => $key) {
if (is_numeric($key) && intval($key) > 0 || $key === '0') {
$key = intval($key);
@@ -61,225 +83,77 @@ public static function check($data, $path = null) {
}
/**
- * Counts the dimensions of an array. If `$all` is set to `false` (which is the default) it will
- * only consider the dimension of the first element in the array.
+ * Creates an associative array using a `$path1` as the path to build its keys, and optionally
+ * `$path2` as path to get the values. If `$path2` is not specified, all values will be
+ * initialized to `null` (useful for `Set::merge()`). You can optionally group the values by
+ * what is obtained when following the path specified in `$groupPath`.
*
- * @param array $data Array to count dimensions on.
- * @param array $options
- * @param integer $count Start the depth count at this number.
- * @return integer The number of dimensions in `$array`.
+ * @param array $data Array from where to extract keys and values.
+ * @param mixed $path1 As an array, or as a dot-delimited string.
+ * @param mixed $path2 As an array, or as a dot-delimited string.
+ * @param string $groupPath As an array, or as a dot-delimited string.
+ * @return array Combined array.
*/
- public static function depth($data, $options = array(), $count = 0) {
+ public static function combine($data, $path1 = null, $path2 = null, $groupPath = null) {
if (empty($data)) {
- return 0;
- }
- if (!is_array($options)) {
- $options = array('all' => $options, 'count' => $count);
- }
- $defaults = array('all' => false, 'count' => 0);
- $options += $defaults;
- if (!empty($options['all'])) {
- $depth = array($options['count']);
- if (is_array($data) && reset($data) !== false) {
- foreach ($data as $value) {
- $depth[] = static::depth($value, array(
- 'all' => $options['all'],
- 'count' => $options['count'] + 1
- ));
- }
- }
- return max($depth);
- }
- if (is_array(reset($data))) {
- return static::depth(reset($data)) + 1;
+ return array();
}
- return 1;
- }
-
- /**
- * Collapses a multi-dimensional array into a single dimension, using a delimited array path
- * for each array element's key, i.e. array(array('Foo' => array('Bar' => 'Far'))) becomes
- * array('0.Foo.Bar' => 'Far').
- *
- * @param array $data array to flatten
- * @param array $options Available options are:
- * - `'separator'`: String to separate array keys in path (defaults to `'.'`).
- * - `'path'`: Starting point (defaults to null).
- * @return array
- */
- public static function flatten($data, $options = array()) {
- $result = array();
-
- if (!is_array($options)) {
- $options = array('separator' => $options);
+ if (is_object($data)) {
+ $data = get_object_vars($data);
}
-
- $defaults = array('separator' => '.', 'path' => null);
- $options += $defaults;
-
- if (!is_null($options['path'])) {
- $options['path'] .= $options['separator'];
+ if (is_array($path1)) {
+ $format = array_shift($path1);
+ $keys = static::format($data, $format, $path1);
+ } else {
+ $keys = static::extract($data, $path1);
}
-
- foreach ($data as $key => $val) {
- if (is_array($val)) {
- $result += (array) static::flatten($val, array(
- 'separator' => $options['separator'],
- 'path' => $options['path'] . $key
- ));
- } else {
- $result[$options['path'] . $key] = $val;
- }
+ $vals = array();
+ if (!empty($path2) && is_array($path2)) {
+ $format = array_shift($path2);
+ $vals = static::format($data, $format, $path2);
+ } elseif (!empty($path2)) {
+ $vals = static::extract($data, $path2);
}
- return $result;
- }
-
- /**
- * Returns a series of values extracted from an array, formatted in a format string.
- *
- * @param array $data Source array from which to extract the data.
- * @param string $format Format string into which values will be inserted using `sprintf()`.
- * @param array $keys An array containing one or more `Set::extract()`-style key paths.
- * @return array An array of strings extracted from `$keys` and formatted with `$format`.
- * @link http://php.net/sprintf
- */
- public static function format($data, $format, $keys) {
-
- $extracted = array();
+ $valCount = count($vals);
$count = count($keys);
- if (!$count) {
- return;
- }
-
- for ($i = 0; $i < $count; $i++) {
- $extracted[] = static::extract($data, $keys[$i]);
+ for ($i = $valCount; $i < $count; $i++) {
+ $vals[$i] = null;
}
- $out = array();
- $data = $extracted;
- $count = count($data[0]);
-
- if (preg_match_all('/\{([0-9]+)\}/msi', $format, $keys2) && isset($keys2[1])) {
- $keys = $keys2[1];
- $format = preg_split('/\{([0-9]+)\}/msi', $format);
- $count2 = count($format);
-
- for ($j = 0; $j < $count; $j++) {
- $formatted = '';
- for ($i = 0; $i <= $count2; $i++) {
- if (isset($format[$i])) {
- $formatted .= $format[$i];
- }
- if (isset($keys[$i]) && isset($data[$keys[$i]][$j])) {
- $formatted .= $data[$keys[$i]][$j];
+ if ($groupPath != null) {
+ $group = static::extract($data, $groupPath);
+ if (!empty($group)) {
+ $c = count($keys);
+ for ($i = 0; $i < $c; $i++) {
+ if (!isset($group[$i])) {
+ $group[$i] = 0;
}
- }
- $out[] = $formatted;
- }
- } else {
- $count2 = count($data);
- for ($j = 0; $j < $count; $j++) {
- $args = array();
- for ($i = 0; $i < $count2; $i++) {
- if (isset($data[$i][$j])) {
- $args[] = $data[$i][$j];
+ if (!isset($out[$group[$i]])) {
+ $out[$group[$i]] = array();
}
+ $out[$group[$i]][$keys[$i]] = $vals[$i];
}
- $out[] = vsprintf($format, $args);
- }
- }
- return $out;
- }
-
- /**
- * Checks to see if all the values in the array are numeric.
- *
- * @param array $array The array to check. If null, the value of the current Set object.
- * @return boolean `true` if values are numeric, `false` otherwise.
- */
- public static function isNumeric($array = null) {
- if (empty($array)) {
- return null;
- }
-
- if ($array === range(0, count($array) - 1)) {
- return true;
- }
-
- $numeric = true;
- $keys = array_keys($array);
- $count = count($keys);
-
- for ($i = 0; $i < $count; $i++) {
- if (!is_numeric($array[$keys[$i]])) {
- $numeric = false;
- break;
+ return $out;
}
}
- return $numeric;
+ return array_combine($keys, $vals);
}
/**
- * This function can be used to see if a single item or a given XPath
- * match certain conditions.
+ * Determines if `val2` is contained in `val1`
*
- * @param mixed $conditions An array of condition strings or an XPath expression.
- * @param array $data An array of data to execute the match on.
- * @param integer $i Optional: The 'nth'-number of the item being matched.
- * @param integer $length
- * @return boolean
+ * @param array $val1 First value.
+ * @param array $val2 Second value.
+ * @return boolean true if `$val1` contains `$val2`, `false` otherwise.
*/
- public static function matches($conditions, $data = array(), $i = null, $length = null) {
- if (empty($conditions)) {
- return true;
- }
- if (is_string($conditions) || is_string($data)) {
- return !!static::extract($data, $conditions);
+ public static function contains($val1, $val2) {
+ if (empty($val1) || empty($val2)) {
+ return false;
}
- foreach ($conditions as $condition) {
- if ($condition === ':last') {
- if ($i != $length) {
- return false;
- }
- continue;
- } elseif ($condition === ':first') {
- if ($i != 1) {
- return false;
- }
- continue;
- }
- if (!preg_match('/(.+?)([><!]?[=]|[><])(.*)/', $condition, $match)) {
- if (ctype_digit($condition)) {
- if ($i != $condition) {
- return false;
- }
- } elseif (preg_match_all('/(?:^[0-9]+|(?<=,)[0-9]+)/', $condition, $matches)) {
- return in_array($i, $matches[0]);
- } elseif (!isset($data[$condition])) {
- return false;
- }
- continue;
- }
-
- list(,$key,$op,$expected) = $match;
- if (!isset($data[$key])) {
- return false;
- }
- $val = $data[$key];
-
- if ($op === '=' && $expected && $expected{0} === '/') {
- return preg_match($expected, $val);
- } elseif ($op === '=' && $val != $expected) {
- return false;
- } elseif ($op === '!=' && $val == $expected) {
- return false;
- } elseif ($op === '>' && $val <= $expected) {
- return false;
- } elseif ($op === '<' && $val >= $expected) {
- return false;
- } elseif ($op === '<=' && $val > $expected) {
- return false;
- } elseif ($op === '>=' && $val < $expected) {
+ foreach ((array) $val2 as $key => $val) {
+ if (is_numeric($key)) {
+ static::contains($val, $val1);
+ } elseif (!isset($val1[$key]) || $val1[$key] != $val) {
return false;
}
}
@@ -287,126 +161,74 @@ public static function matches($conditions, $data = array(), $i = null, $length
}
/**
- * Maps the contents of the Set object to an object hierarchy. Maintains numeric
- * keys as arrays of objects.
- *
- * @param array $data The array.
- * @param string $class A class name of the type of object to map to.
- * @param boolean $name whether the _name_ should be filled.
- * @return object Hierarchical object.
- */
- public static function map($data, $class = 'stdClass', $name = false) {
- if (empty($data)) {
- return $data;
- }
- if ($class === true) {
- $out = new \stdClass;
- } else {
- $out = new $class;
- }
-
- if (is_array($data)) {
- $keys = array_keys($data);
- foreach ($data as $key => $value) {
- if ($keys[0] === $key && $class !== true) {
- $name = true;
- }
- if (is_numeric($key)) {
- if (is_object($out)) {
- $out = get_object_vars($out);
- }
- $out[$key] = static::map($value, $class);
- $isNamed = (
- is_object($out[$key]) && !isset($out[$key]->_name_) &&
- $name !== true && static::depth($value, true) >= 2
- );
- if ($isNamed) {
- $out[$key]->_name_ = $name;
- }
- } elseif (is_array($value)) {
- if ($name === true) {
- $out->_name_ = $key;
- $name = false;
- foreach ($value as $key2 => $value2) {
- $out->{$key2} = static::map($value2, true);
- }
- } else {
- if (!is_numeric($key)) {
- $out->{$key} = static::map($value, true, $key);
- if (is_object($out->{$key}) && !isset($out->{$key}->_name_)) {
- $out->{$key}->_name_ = $key;
- }
- } else {
- $out->{$key} = static::map($value, true);
- }
- }
- } else {
- $out->{$key} = $value;
- }
- }
- } else {
- $out = $data;
- }
- return $out;
- }
-
- /**
- * This function can be thought of as a hybrid between PHP's `array_merge()`
- * and `array_merge_recursive()`. The difference to the two is that if an
- * array key contains another array then the function behaves recursive
- * (unlike `array_merge()`) but does not do if for keys containing strings
- * (unlike `array_merge_recursive()`). Please note: This function will work
- * with an unlimited amount of arguments and typecasts non-array parameters
- * into arrays.
+ * Counts the dimensions of an array. If `$all` is set to `false` (which is the default) it will
+ * only consider the dimension of the first element in the array.
*
- * @param array $arr1 Array to be merged.
- * @param array $arr2 Array to merge with.
- * @return array Merged array.
+ * @param array $data Array to count dimensions on.
+ * @param array $options
+ * @param integer $count Start the depth count at this number.
+ * @return integer The number of dimensions in `$array`.
*/
- public static function merge($arr1, $arr2 = null) {
- $args = func_get_args();
-
- if (!isset($result)) {
- $result = (array) current($args);
+ public static function depth($data, $options = array(), $count = 0) {
+ if (empty($data)) {
+ return 0;
+ }
+ if (!is_array($options)) {
+ $options = array('all' => $options, 'count' => $count);
}
+ $defaults = array('all' => false, 'count' => 0);
+ $options += $defaults;
- while (($arg = next($args)) !== false) {
- foreach ((array) $arg as $key => $val) {
- if (is_array($val) && isset($result[$key]) && is_array($result[$key])) {
- $result[$key] = static::merge($result[$key], $val);
- } elseif (is_int($key)) {
- $result[] = $val;
- } else {
- $result[$key] = $val;
+ if (!empty($options['all'])) {
+ $depth = array($options['count']);
+ if (is_array($data) && reset($data) !== false) {
+ foreach ($data as $value) {
+ $depth[] = static::depth($value, array(
+ 'all' => $options['all'],
+ 'count' => $options['count'] + 1
+ ));
}
}
+ return max($depth);
}
- return $result;
+ if (is_array(reset($data))) {
+ return static::depth(reset($data)) + 1;
+ }
+ return 1;
}
/**
- * Pushes the differences in `$array2` onto the end of `$array`.
+ * Computes the difference between two arrays.
*
- * @param mixed $array Original array.
- * @param mixed $array2 Differences to push.
- * @return array Combined array.
+ * @param mixed $val1 First value.
+ * @param mixed $val2 Second value.
+ * @return array Computed difference.
*/
- public static function pushDiff($array, $array2) {
- if (empty($array) && !empty($array2)) {
- return $array2;
+ public static function diff($val1, $val2 = null) {
+ if (empty($val1)) {
+ return (array) $val2;
+ } elseif (empty($val2)) {
+ return (array) $val1;
}
- if (!empty($array) && !empty($array2)) {
- foreach ($array2 as $key => $value) {
- if (!isset($array[$key])) {
- $array[$key] = $value;
- } else {
- if (is_array($value)) {
- $array[$key] = static::pushDiff($array[$key], $array2[$key]);
- }
- }
+ $out = array();
+
+ foreach ($val1 as $key => $val) {
+ $exists = isset($val2[$key]);
+
+ if ($exists && $val2[$key] != $val) {
+ $out[$key] = $val;
+ } elseif (!$exists) {
+ $out[$key] = $val;
}
+ unset($val2[$key]);
}
- return $array;
+
+ foreach ($val2 as $key => $val) {
+ if (!isset($out[$key])) {
+ $out[$key] = $val;
+ }
+ }
+ return $out;
}
/**
@@ -436,20 +258,17 @@ public static function extract($data, $path = null, $options = array()) {
if (empty($data)) {
return array();
}
-
if (is_string($data)) {
$tmp = $path;
$path = $data;
$data = $tmp;
unset($tmp);
}
-
if ($path === '/') {
return array_filter($data, function($data) {
return ($data === 0 || $data === '0' || !empty($data));
});
}
-
$contexts = $data;
$options = array_merge(array('flatten' => true), $options);
@@ -573,6 +392,97 @@ public static function extract($data, $path = null, $options = array()) {
}
/**
+ * Collapses a multi-dimensional array into a single dimension, using a delimited array path
+ * for each array element's key, i.e. array(array('Foo' => array('Bar' => 'Far'))) becomes
+ * array('0.Foo.Bar' => 'Far').
+ *
+ * @param array $data array to flatten
+ * @param array $options Available options are:
+ * - `'separator'`: String to separate array keys in path (defaults to `'.'`).
+ * - `'path'`: Starting point (defaults to null).
+ * @return array
+ */
+ public static function flatten($data, $options = array()) {
+ $result = array();
+
+ if (!is_array($options)) {
+ $options = array('separator' => $options);
+ }
+ $defaults = array('separator' => '.', 'path' => null);
+ $options += $defaults;
+
+ if (!is_null($options['path'])) {
+ $options['path'] .= $options['separator'];
+ }
+ foreach ($data as $key => $val) {
+ if (is_array($val)) {
+ $result += (array) static::flatten($val, array(
+ 'separator' => $options['separator'],
+ 'path' => $options['path'] . $key
+ ));
+ } else {
+ $result[$options['path'] . $key] = $val;
+ }
+ }
+ return $result;
+ }
+
+ /**
+ * Returns a series of values extracted from an array, formatted in a format string.
+ *
+ * @param array $data Source array from which to extract the data.
+ * @param string $format Format string into which values will be inserted using `sprintf()`.
+ * @param array $keys An array containing one or more `Set::extract()`-style key paths.
+ * @return array An array of strings extracted from `$keys` and formatted with `$format`.
+ * @link http://php.net/sprintf
+ */
+ public static function format($data, $format, $keys) {
+ $extracted = array();
+ $count = count($keys);
+
+ if (!$count) {
+ return;
+ }
+ for ($i = 0; $i < $count; $i++) {
+ $extracted[] = static::extract($data, $keys[$i]);
+ }
+ $out = array();
+ $data = $extracted;
+ $count = count($data[0]);
+
+ if (preg_match_all('/\{([0-9]+)\}/msi', $format, $keys2) && isset($keys2[1])) {
+ $keys = $keys2[1];
+ $format = preg_split('/\{([0-9]+)\}/msi', $format);
+ $count2 = count($format);
+
+ for ($j = 0; $j < $count; $j++) {
+ $formatted = '';
+ for ($i = 0; $i <= $count2; $i++) {
+ if (isset($format[$i])) {
+ $formatted .= $format[$i];
+ }
+ if (isset($keys[$i]) && isset($data[$keys[$i]][$j])) {
+ $formatted .= $data[$keys[$i]][$j];
+ }
+ }
+ $out[] = $formatted;
+ }
+ } else {
+ $count2 = count($data);
+ for ($j = 0; $j < $count; $j++) {
+ $args = array();
+ for ($i = 0; $i < $count2; $i++) {
+ if (isset($data[$i][$j])) {
+ $args[] = $data[$i][$j];
+ }
+ }
+ $out[] = vsprintf($format, $args);
+ }
+ }
+ return $out;
+ }
+
+ /**
* Inserts `$data` into an array as defined by `$path`.
*
* @param mixed $list Where to insert into.
@@ -603,93 +513,129 @@ public static function insert($list, $path, $data = null) {
}
/**
- * Removes an element from an array as defined by `$path`.
+ * Checks to see if all the values in the array are numeric.
*
- * @param mixed $list From where to remove.
- * @param mixed $path A dot-delimited string.
- * @return array Array with `$path` removed from its value.
+ * @param array $array The array to check. If null, the value of the current Set object.
+ * @return boolean `true` if values are numeric, `false` otherwise.
*/
- public static function remove($list, $path = null) {
- if (empty($path)) {
- return $list;
+ public static function isNumeric($array = null) {
+ if (empty($array)) {
+ return null;
}
- if (!is_array($path)) {
- $path = explode('.', $path);
+ if ($array === range(0, count($array) - 1)) {
+ return true;
}
- $_list =& $list;
+ $numeric = true;
+ $keys = array_keys($array);
+ $count = count($keys);
- foreach ($path as $i => $key) {
- if (is_numeric($key) && intval($key) > 0 || $key === '0') {
- $key = intval($key);
- }
- if ($i === count($path) - 1) {
- unset($_list[$key]);
- } else {
- if (!isset($_list[$key])) {
- return $list;
- }
- $_list =& $_list[$key];
+ for ($i = 0; $i < $count; $i++) {
+ if (!is_numeric($array[$keys[$i]])) {
+ $numeric = false;
+ break;
}
}
- return $list;
+ return $numeric;
}
/**
- * Computes the difference between two arrays.
+ * This function can be used to see if a single item or a given XPath
+ * match certain conditions.
*
- * @param mixed $val1 First value.
- * @param mixed $val2 Second value.
- * @return array Computed difference.
+ * @param mixed $conditions An array of condition strings or an XPath expression.
+ * @param array $data An array of data to execute the match on.
+ * @param integer $i Optional: The 'nth'-number of the item being matched.
+ * @param integer $length
+ * @return boolean
*/
- public static function diff($val1, $val2 = null) {
- if (empty($val1)) {
- return (array) $val2;
- } elseif (empty($val2)) {
- return (array) $val1;
+ public static function matches($conditions, $data = array(), $i = null, $length = null) {
+ if (empty($conditions)) {
+ return true;
}
- $out = array();
-
- foreach ($val1 as $key => $val) {
- $exists = isset($val2[$key]);
+ if (is_string($conditions) || is_string($data)) {
+ return !!static::extract($data, $conditions);
+ }
+ foreach ($conditions as $condition) {
+ if ($condition === ':last') {
+ if ($i != $length) {
+ return false;
+ }
+ continue;
+ } elseif ($condition === ':first') {
+ if ($i != 1) {
+ return false;
+ }
+ continue;
+ }
+ if (!preg_match('/(.+?)([><!]?[=]|[><])(.*)/', $condition, $match)) {
+ if (ctype_digit($condition)) {
+ if ($i != $condition) {
+ return false;
+ }
+ } elseif (preg_match_all('/(?:^[0-9]+|(?<=,)[0-9]+)/', $condition, $matches)) {
+ return in_array($i, $matches[0]);
+ } elseif (!isset($data[$condition])) {
+ return false;
+ }
+ continue;
+ }
+ list(,$key,$op,$expected) = $match;
- if ($exists && $val2[$key] != $val) {
- $out[$key] = $val;
- } elseif (!$exists) {
- $out[$key] = $val;
+ if (!isset($data[$key])) {
+ return false;
}
- unset($val2[$key]);
- }
+ $val = $data[$key];
- foreach ($val2 as $key => $val) {
- if (!isset($out[$key])) {
- $out[$key] = $val;
+ if ($op === '=' && $expected && $expected{0} === '/') {
+ return preg_match($expected, $val);
+ } elseif ($op === '=' && $val != $expected) {
+ return false;
+ } elseif ($op === '!=' && $val == $expected) {
+ return false;
+ } elseif ($op === '>' && $val <= $expected) {
+ return false;
+ } elseif ($op === '<' && $val >= $expected) {
+ return false;
+ } elseif ($op === '<=' && $val > $expected) {
+ return false;
+ } elseif ($op === '>=' && $val < $expected) {
+ return false;
}
}
- return $out;
+ return true;
}
/**
- * Determines if one array contains the exact keys and values of another.
+ * This function can be thought of as a hybrid between PHP's `array_merge()`
+ * and `array_merge_recursive()`. The difference to the two is that if an
+ * array key contains another array then the function behaves recursive
+ * (unlike `array_merge()`) but does not do if for keys containing strings
+ * (unlike `array_merge_recursive()`). Please note: This function will work
+ * with an unlimited amount of arguments and typecasts non-array parameters
+ * into arrays.
*
- * @param array $val1 First value.
- * @param array $val2 Second value.
- * @return boolean true if `$val1` contains `$val2`, `false` otherwise.
+ * @return array Merged array of all passed params.
*/
- public static function contains($val1, $val2 = null) {
- if (empty($val1) || empty($val2)) {
- return false;
+ public static function merge() {
+ $args = func_get_args();
+
+ if (empty($args[0])) {
+ return array();
}
+ $result = (array) current($args);
- foreach ($val2 as $key => $val) {
- if (is_numeric($key)) {
- static::contains($val, $val1);
- } else {
- if (!isset($val1[$key]) || $val1[$key] != $val) {
- return false;
+ while (($arg = next($args)) !== false) {
+ foreach ((array) $arg as $key => $val) {
+ if (is_array($val) && isset($result[$key]) && is_array($result[$key])) {
+ $result[$key] = static::merge($result[$key], $val);
+ } elseif (is_int($key)) {
+ $result[] = $val;
+ } else {
+ $result[$key] = $val;
}
}
}
- return true;
+ return $result;
}
/**
@@ -742,63 +688,77 @@ public static function normalize($list, $assoc = true, $sep = ',', $trim = true)
}
/**
- * Creates an associative array using a `$path1` as the path to build its keys, and optionally
- * `$path2` as path to get the values. If `$path2` is not specified, all values will be
- * initialized to `null` (useful for `Set::merge()`). You can optionally group the values by
- * what is obtained when following the path specified in `$groupPath`.
+ * Removes an element from an array as defined by `$path`.
*
- * @param array $data Array from where to extract keys and values.
- * @param mixed $path1 As an array, or as a dot-delimited string.
- * @param mixed $path2 As an array, or as a dot-delimited string.
- * @param string $groupPath As an array, or as a dot-delimited string.
- * @return array Combined array.
+ * @param mixed $list From where to remove.
+ * @param mixed $path A dot-delimited string.
+ * @return array Array with `$path` removed from its value.
*/
- public static function combine($data, $path1 = null, $path2 = null, $groupPath = null) {
- if (empty($data)) {
- return array();
- }
-
- if (is_object($data)) {
- $data = get_object_vars($data);
- }
-
- if (is_array($path1)) {
- $format = array_shift($path1);
- $keys = static::format($data, $format, $path1);
- } else {
- $keys = static::extract($data, $path1);
+ public static function remove($list, $path = null) {
+ if (empty($path)) {
+ return $list;
}
- $vals = array();
- if (!empty($path2) && is_array($path2)) {
- $format = array_shift($path2);
- $vals = static::format($data, $format, $path2);
- } elseif (!empty($path2)) {
- $vals = static::extract($data, $path2);
+ if (!is_array($path)) {
+ $path = explode('.', $path);
}
+ $_list =& $list;
- $valCount = count($vals);
- $count = count($keys);
- for ($i = $valCount; $i < $count; $i++) {
- $vals[$i] = null;
+ foreach ($path as $i => $key) {
+ if (is_numeric($key) && intval($key) > 0 || $key === '0') {
+ $key = intval($key);
+ }
+ if ($i === count($path) - 1) {
+ unset($_list[$key]);
+ } else {
+ if (!isset($_list[$key])) {
+ return $list;
+ }
+ $_list =& $_list[$key];
+ }
}
+ return $list;
+ }
- if ($groupPath != null) {
- $group = static::extract($data, $groupPath);
- if (!empty($group)) {
- $c = count($keys);
- for ($i = 0; $i < $c; $i++) {
- if (!isset($group[$i])) {
- $group[$i] = 0;
- }
- if (!isset($out[$group[$i]])) {
- $out[$group[$i]] = array();
- }
- $out[$group[$i]][$keys[$i]] = $vals[$i];
+ /**
+ * Sorts an array by any value, determined by a `Set`-compatible path.
+ *
+ * @param array $data
+ * @param string $path A `Set`-compatible path to the array value.
+ * @param string $dir Either `'asc'` (the default) or `'desc'`.
+ * @return array
+ */
+ public static function sort($data, $path, $dir = 'asc') {
+ $flatten = function($flatten, $results, $key = null) {
+ $stack = array();
+ foreach ((array) $results as $k => $r) {
+ $id = $k;
+ if (!is_null($key)) {
+ $id = $key;
+ }
+ if (is_array($r)) {
+ $stack = array_merge($stack, $flatten($flatten, $r, $id));
+ } else {
+ $stack[] = array('id' => $id, 'value' => $r);
}
- return $out;
}
+ return $stack;
+ };
+ $extract = static::extract($data, $path);
+ $result = $flatten($flatten, $extract);
+
+ list($keys, $values) = array(
+ static::extract($result, '/id'),
+ static::extract($result, '/value')
+ );
+ $dir = ($dir === 'desc') ? SORT_DESC : SORT_ASC;
+ array_multisort($values, $dir, $keys, $dir);
+ $sorted = array();
+ $keys = array_unique($keys);
+
+ foreach ($keys as $k) {
+ $sorted[] = $data[$k];
}
- return array_combine($keys, $vals);
+ return $sorted;
}
/**
@@ -808,7 +768,7 @@ public static function combine($data, $path1 = null, $path2 = null, $groupPath =
* @param object $object Object to reverse.
* @return array
*/
- public static function reverse($object) {
+ public static function toArray($object) {
$out = array();
if (is_object($object)) {
$keys = get_object_vars($object);
@@ -819,12 +779,12 @@ public static function reverse($object) {
$new = array();
foreach ($keys as $key => $value) {
if (is_array($value)) {
- $new[$key] = static::reverse($value);
+ $new[$key] = static::toArray($value);
} else {
if (isset($value->_name_)) {
- $new = array_merge($new, static::reverse($value));
+ $new = array_merge($new, static::toArray($value));
} else {
- $new[$key] = static::reverse($value);
+ $new[$key] = static::toArray($value);
}
}
}
@@ -835,7 +795,7 @@ public static function reverse($object) {
}
} elseif (is_array($object)) {
foreach ($object as $key => $value) {
- $out[$key] = static::reverse($value);
+ $out[$key] = static::toArray($value);
}
} else {
$out = $object;
@@ -844,50 +804,67 @@ public static function reverse($object) {
}
/**
- * Sorts an array by any value, determined by a `Set`-compatible path.
+ * Maps the contents of the Set object to an object hierarchy. Maintains numeric
+ * keys as arrays of objects.
*
- * @param array $data
- * @param string $path A `Set`-compatible path to the array value.
- * @param string $dir Either `'asc'` (the default) or `'desc'`.
- * @return array
+ * @param array $data The array.
+ * @param string $class A class name of the type of object to map to.
+ * @param boolean $name whether the _name_ should be filled.
+ * @return object Hierarchical object.
*/
- public static function sort($data, $path, $dir = 'asc') {
- $flatten = function($flatten, $results, $key = null) {
- $stack = array();
- foreach ((array) $results as $k => $r) {
- $id = $k;
- if (!is_null($key)) {
- $id = $key;
+ public static function toObject($data, $class = 'stdClass', $name = false) {
+ if (empty($data)) {
+ return $data;
+ }
+ if ($class === true) {
+ $out = new \stdClass;
+ } else {
+ $out = new $class;
+ }
+
+ if (is_array($data)) {
+ $keys = array_keys($data);
+ foreach ($data as $key => $value) {
+ if ($keys[0] === $key && $class !== true) {
+ $name = true;
}
- if (is_array($r)) {
- $stack = array_merge($stack, $flatten($flatten, $r, $id));
+ if (is_numeric($key)) {
+ if (is_object($out)) {
+ $out = get_object_vars($out);
+ }
+ $out[$key] = static::toObject($value, $class);
+ $isNamed = (
+ is_object($out[$key]) && !isset($out[$key]->_name_) &&
+ $name !== true && static::depth($value, true) >= 2
+ );
+ if ($isNamed) {
+ $out[$key]->_name_ = $name;
+ }
+ } elseif (is_array($value)) {
+ if ($name === true) {
+ $out->_name_ = $key;
+ $name = false;
+ foreach ($value as $key2 => $value2) {
+ $out->{$key2} = static::toObject($value2, true);
+ }
+ } else {
+ if (!is_numeric($key)) {
+ $out->{$key} = static::toObject($value, true, $key);
+ if (is_object($out->{$key}) && !isset($out->{$key}->_name_)) {
+ $out->{$key}->_name_ = $key;
+ }
+ } else {
+ $out->{$key} = static::toObject($value, true);
+ }
+ }
} else {
- $stack[] = array('id' => $id, 'value' => $r);
+ $out->{$key} = $value;
}
}
- return $stack;
- };
- $extract = static::extract($data, $path);
- $result = $flatten($flatten, $extract);
-
- list($keys, $values) = array(
- static::extract($result, '/id'),
- static::extract($result, '/value')
- );
- if ($dir === 'desc') {
- $dir = SORT_DESC;
} else {
- $dir = SORT_ASC;
- }
-
- array_multisort($values, $dir, $keys, $dir);
- $sorted = array();
- $keys = array_unique($keys);
-
- foreach ($keys as $k) {
- $sorted[] = $data[$k];
+ $out = $data;
}
- return $sorted;
+ return $out;
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.