Skip to content

Instantly share code, notes, and snippets.

@correl
Created November 13, 2013 13:53
Show Gist options
  • Save correl/7449471 to your computer and use it in GitHub Desktop.
Save correl/7449471 to your computer and use it in GitHub Desktop.
Manipulating multidimensional data structures in PHP
<?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;
}
<?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