Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Moving flatten() across.
It is no longer recursive either.
  • Loading branch information
markstory committed Mar 27, 2012
1 parent 51e3ee0 commit 51f45c0
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 1 deletion.
55 changes: 55 additions & 0 deletions lib/Cake/Test/Case/Utility/Set2Test.php
Expand Up @@ -221,4 +221,59 @@ public function testMaxDimensions() {
$this->assertEquals($result, 5);
}

/**
* Tests Set::flatten
*
* @return void
*/
public function testFlatten() {
$data = array('Larry', 'Curly', 'Moe');
$result = Set2::flatten($data);
$this->assertEquals($result, $data);

$data[9] = 'Shemp';
$result = Set2::flatten($data);
$this->assertEquals($result, $data);

$data = 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),
)
);

$result = Set2::flatten($data);
$expected = 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
);
$this->assertEquals($expected, $result);

$data = array(
array('Post' => array('id' => 1)),
array('Post' => array('id' => 2)),
);
$result = Set2::flatten($data, '/');
$expected = array(
'0/Post/id' => '1',
'1/Post/id' => '2',
);
$this->assertEquals($expected, $result);
}

}
36 changes: 35 additions & 1 deletion lib/Cake/Utility/Set2.php
Expand Up @@ -82,8 +82,42 @@ public static function filter(array $data) {

}

public static function flatten(array $data) {
/**
* 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 string $separator String used to separate array key elements in a path, defaults to '.'
* @return array
* @link http://book.cakephp.org/2.0/en/core-utility-libraries/set.html#Set::flatten
*/
public static function flatten(array $data, $separator = '.') {
$result = array();
$stack = array();
$path = null;

reset($data);
while (!empty($data)) {
$key = key($data);
$element = $data[$key];
unset($data[$key]);

if (is_array($element)) {
if (!empty($data)) {
$stack[] = array($data, $path);
}
$data = $element;
$path .= $key . $separator;
} else {
$result[$path . $key] = $element;
}

if (empty($data) && !empty($stack)) {
list($data, $path) = array_pop($stack);
}
}
return $result;
}

public static function merge(array $data, $merge) {
Expand Down

0 comments on commit 51f45c0

Please sign in to comment.