Set::expand as implemented by jeremyharris

This commit is contained in:
Rachman Chavik 2012-03-15 20:07:49 +07:00
parent 8fdb11121e
commit 079ae8265c
2 changed files with 76 additions and 0 deletions

View file

@ -3129,6 +3129,52 @@ class SetTest extends CakeTestCase {
$this->assertEquals($expected, $result);
}
/**
* Tests Set::expand
*
* @return void
*/
public function testExpand() {
$data = array('My', 'Array', 'To', 'Flatten');
$flat = Set::flatten($data);
$result = Set::expand($flat);
$this->assertEqual($data, $result);
$data = array(
'0.Post.id' => '1', '0.Post.author_id' => '1', '0.Post.title' => 'First Post', '0.Author.id' => '1',
'0.Author.user' => 'nate', '0.Author.password' => 'foo', '1.Post.id' => '2', '1.Post.author_id' => '3',
'1.Post.title' => 'Second Post', '1.Post.body' => 'Second Post Body', '1.Author.id' => '3',
'1.Author.user' => 'larry', '1.Author.password' => null
);
$result = Set::expand($data);
$expected = array(
array(
'Post' => array('id' => '1', 'author_id' => '1', 'title' => 'First Post'),
'Author' => array('id' => '1', 'user' => 'nate', 'password' => 'foo'),
),
array(
'Post' => array('id' => '2', 'author_id' => '3', 'title' => 'Second Post', 'body' => 'Second Post Body'),
'Author' => array('id' => '3', 'user' => 'larry', 'password' => null),
)
);
$this->assertEqual($result, $expected);
$data = array(
'0/Post/id' => 1,
'0/Post/name' => 'test post'
);
$result = Set::expand($data, '/');
$expected = array(
array(
'Post' => array(
'id' => 1,
'name' => 'test post'
)
)
);
$this->assertEqual($result, $expected);
}
/**
* test normalization
*

View file

@ -1036,6 +1036,36 @@ class Set {
return $result;
}
/**
* Expand/unflattens an string to an array
*
* For example, unflattens an array that was collapsed with `Set::flatten()`
* into a multi-dimensional array. So, `array('0.Foo.Bar' => 'Far')` becomes
* `array(array('Foo' => array('Bar' => 'Far')))`.
*
* @param array $data Flattened array
* @param string $separator The delimiter used
* @return array
*/
public static function expand($data, $separator = '.') {
$result = array();
foreach ($data as $flat => $value) {
$keys = explode($separator, $flat);
$keys = array_reverse($keys);
$child = array(
$keys[0] => $value
);
array_shift($keys);
foreach ($keys as $k) {
$child = array(
$k => $child
);
}
$result = Set::merge($result, $child);
}
return $result;
}
/**
* Flattens an array for sorting
*