Created
November 13, 2013 13:53
-
-
Save correl/7449471 to your computer and use it in GitHub Desktop.
Manipulating multidimensional data structures in PHP
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class KeyError extends Exception {}; | |
function filter_tree($tree, $fields) { | |
if (empty($fields)) | |
{ | |
return $tree; | |
} | |
$result = array(); | |
foreach ($fields as $field) | |
{ | |
$result = recursive_set($result, | |
$field, | |
recursive_get($tree, $field)); | |
} | |
return $result; | |
} | |
function recursive_get($tree, $fields) | |
{ | |
$get = function($tree, $field) { | |
if (!isset($tree[$field])) | |
{ | |
throw new KeyError($field); | |
} | |
return $tree[$field]; | |
}; | |
return array_reduce($fields, | |
$get, | |
$tree); | |
} | |
function recursive_set($tree, $fields, $value) | |
{ | |
$ref = &$tree; | |
foreach ($fields as $field) | |
{ | |
if (!isset($ref[$field])) | |
$ref[$field] = array(); | |
$ref = &$ref[$field]; | |
} | |
$ref = $value; | |
return $tree; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
require_once("filter.php"); | |
class FilterTests extends PHPUnit_Framework_TestCase { | |
public function testFilter1D() { | |
$data = array('foo' => 'bar', | |
'baz' => 'quux'); | |
$filtered = filter_tree($data, | |
array(array('foo'))); | |
$this->assertEquals(array('foo' => 'bar'), | |
$filtered); | |
} | |
public function testFilter2D() { | |
$data = array('foo' => array('a' => 1, | |
'b' => 2), | |
'bar' => 'baz'); | |
$filtered = filter_tree($data, | |
array(array('foo', 'b'))); | |
$this->assertEquals(array('foo' => array('b' => 2)), | |
$filtered); | |
} | |
public function testFilterMultiple() { | |
$data = array('foo' => array('a' => 1, | |
'b' => 2), | |
'bar' => array('a' => array(), | |
'b' => array('name' => 'MyName', | |
'description' => 'Description')), | |
'baz' => array('a' => 123)); | |
$filtered = filter_tree($data, | |
array(array('foo', 'b'), | |
array('bar', 'b', 'description'), | |
array('baz'))); | |
$this->assertEquals(array('foo' => array('b' => 2), | |
'bar' => array('b' => array('description' => 'Description')), | |
'baz' => array('a' => 123)), | |
$filtered); | |
} | |
public function testFilterNone() { | |
$data = array('foo' => array('a' => 1, | |
'b' => 2), | |
'bar' => array('a' => array(), | |
'b' => array('name' => 'MyName', | |
'description' => 'Description')), | |
'baz' => array('a' => 123)); | |
$this->assertEquals($data, | |
filter_tree($data, array())); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment