diff --git a/README.md b/README.md index 3787905..812c595 100644 --- a/README.md +++ b/README.md @@ -113,6 +113,15 @@ Bottomline is based on namespaces and dynamic autoloader. The main file is `load // → [1, 2, 3, 4] ``` + - [__::patch](src/__/arrays/patch.php) + + Patches array with list of xpath-value pairs. + + ```php + __::patch(['addr' => ['country' => 'US', 'zip' => 12345]], ['/addr/country' => 'CA', '/addr/zip' => 54321]); + // → ['addr' => ['country' => 'CA', 'zip' => 54321]] + ``` + - [__::prepend](src/__/arrays/prepend.php) ```php diff --git a/src/__/arrays/patch.php b/src/__/arrays/patch.php new file mode 100644 index 0000000..2f0b5a1 --- /dev/null +++ b/src/__/arrays/patch.php @@ -0,0 +1,45 @@ + ['country' => 'US', 'zip' => 12345]], ['/addr/country' => 'CA', '/addr/zip' => 54321]); + ** // → ['addr' => ['country' => 'CA', 'zip' => 54321]] + */ + +function patch($arr, $patches, $parent = '') +{ + foreach($arr as $key => $value) + { + $z = $parent . '/' . $key; + + if( isset($patches[$z]) ) + { + $arr[ $key ] = $patches[$z]; + unset( $patches[$z] ); + + if( !count($patches) ) + { + break; + } + } + + if( is_array($value) ) + { + $arr[ $key ] = patch($value, $patches, $z); + } + } + + return $arr; +} diff --git a/tests/arrays.php b/tests/arrays.php index ddc6bee..b816c37 100644 --- a/tests/arrays.php +++ b/tests/arrays.php @@ -40,6 +40,19 @@ public function testFlatten() $this->assertEquals([1, 2, 3, 4], $x); } + public function testPatch() + { + // Arrange + $a = [1, 1, 1, 'contacts' => ['country' => 'US', 'tel' => [123]], 99]; + $p = ['/0' => 2, '/1' => 3, '/contacts/country' => 'CA', '/contacts/tel/0' => 3456]; + + // Act + $x = __::patch($a, $p); + + // Assert + $this->assertEquals([2, 3, 1, 'contacts' => ['country' => 'CA', 'tel' => [3456]], 99], $x); + } + public function testPrepend() { // Arrange