Skip to content
This repository has been archived by the owner on May 15, 2021. It is now read-only.

Commit

Permalink
:octocat: array helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
codemasher committed Dec 30, 2017
1 parent f9cfb5c commit 47a2dd7
Show file tree
Hide file tree
Showing 5 changed files with 372 additions and 36 deletions.
65 changes: 37 additions & 28 deletions src/ArrayHelpers/DotArray.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,47 @@
*
* @filesource DotArray.php
* @created 13.11.2017
* @package chillerlan\Traits
* @package chillerlan\Traits\ArrayHelpers
* @author Smiley <[email protected]>
* @copyright 2017 Smiley
* @license MIT
*/

namespace chillerlan\Traits;
namespace chillerlan\Traits\ArrayHelpers;

/**
* @link https://github.com/laravel/framework/blob/5.4/src/Illuminate/Support/Arr.php
*/
trait DotArray{

/**
* @var array
*/
protected $array;

/**
* Checks if $key isset in $array using dot notation and returns it on success.
*
* @param array $array the array to search in
* @param string $key the key to search
* @param string $dotKey the key to search
* @param mixed $default [optional] a default value in case the key isn't being found
*
* @return mixed returns $array[$key], $default otherwise.
*/
protected function arrayGet(array $array, string $key, $default = null){
public function get(string $dotKey, $default = null){

if(isset($array[$key])){
return $array[$key];
if(isset($this->array[$dotKey])){
return $this->array[$dotKey];
}

foreach(explode('.', $key) as $segment){
$array = &$this->array;

foreach(explode('.', $dotKey) as $segment){

if(!is_array($array) || !array_key_exists($segment, $array)){
return $default;
}

$array = $array[$segment];
$array = &$array[$segment];
}

return $array;
Expand All @@ -47,28 +53,29 @@ protected function arrayGet(array $array, string $key, $default = null){
/**
* Checks if $key exists in $array using dot notation and returns it on success
*
* @param array $array the array to search in
* @param string $key the key to search
* @param string $dotKey the key to search
*
* @return bool
*/
protected function arrayIn(array $array, string $key):bool{
public function in(string $dotKey):bool{

if(empty($array)){
if(empty($this->array)){
return false;
}

if(array_key_exists($key, $array)){
if(array_key_exists($dotKey, $this->array)){
return true;
}

foreach(explode('.', $key) as $segment){
$array = &$this->array;

foreach(explode('.', $dotKey) as $segment){

if(!is_array($array) || !array_key_exists($segment, $array)){
return false;
}

$array = $array[$segment];
$array = &$array[$segment];
}

return true;
Expand All @@ -79,36 +86,38 @@ protected function arrayIn(array $array, string $key):bool{
*
* If no key is given to the method, the entire array will be replaced.
*
* @param array $array
* @param string $key
* @param string $dotKey
* @param mixed $value
*
* @return array
* @return \chillerlan\Traits\ArrayHelpers\DotArray
*/
protected function arraySet(array &$array, string $key, $value){
public function set(string $dotKey, $value){

if(empty($dotKey)){
$this->array = $value;

if(is_null($key)){
return $array = $value;
return $this;
}

$keys = explode('.', $key);
$array = &$this->array;
$keys = explode('.', $dotKey);

while(count($keys) > 1){
$key = array_shift($keys);
$dotKey = array_shift($keys);

// If the key doesn't exist at this depth, we will just create an empty array
// to hold the next value, allowing us to create the arrays to hold final
// values at the correct depth. Then we'll keep digging into the array.
if(!isset($array[$key]) || !is_array($array[$key])){
$array[$key] = [];
if(!isset($array[$dotKey]) || !is_array($array[$dotKey])){
$array[$dotKey] = [];
}

$array = &$array[$key];
$array = &$array[$dotKey];
}

$array[array_shift($keys)] = $value;

return $array;
return $this;
}

}
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
<?php
/**
* Trait ArraySearch
* Trait SearchableArray
*
* @filesource ArraySearch.php
* @filesource SearchableArray.php.php
* @created 04.12.2017
* @package chillerlan\Traits
* @package chillerlan\Traits\ArrayHelpers
* @author Smiley <[email protected]>
* @copyright 2017 Smiley
* @license MIT
*/

namespace chillerlan\Traits;
namespace chillerlan\Traits\ArrayHelpers;

use ArrayIterator, ArrayObject, RecursiveArrayIterator, RecursiveIteratorIterator, Traversable;

class ArraySearch{
trait SearchableArray{
use DotArray;

/**
* @var \IteratorIterator|\RecursiveIteratorIterator
Expand All @@ -39,6 +40,7 @@ public function __construct($array = null){
elseif($array instanceof Traversable){
$this->array = iterator_to_array($array);
}
// yields unexpected results with DotArray
elseif(gettype($array) === 'object'){
$this->array = get_object_vars($array);
}
Expand All @@ -48,15 +50,14 @@ public function __construct($array = null){
else{
$this->array = [];
}

}

/**
* @param string $dotKey
*
* @return mixed
*/
public function arraySearch(string $dotKey){
public function search(string $dotKey){
$this->iterator = $this->getRecursiveIteratorIterator();

foreach($this->iterator as $v){
Expand All @@ -75,7 +76,7 @@ public function arraySearch(string $dotKey){
*
* @return bool
*/
public function arrayIsset(string $dotKey):bool{
public function isset(string $dotKey):bool{
$this->iterator = $this->getRecursiveIteratorIterator();

foreach($this->iterator as $v){
Expand Down
40 changes: 40 additions & 0 deletions tests/ArrayTrait/ArrayTraitTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php
/**
*
* @filesource ArrayTraitTest.php
* @created 04.12.2017
* @package chillerlan\TraitTest\ArrayTrait
* @author Smiley <[email protected]>
* @copyright 2017 Smiley
* @license MIT
*/

namespace chillerlan\TraitTest\ArrayTrait;

use PHPUnit\Framework\TestCase;

class SearchableArrayTest extends TestCase{

public function testSearchableArray(){
// https://api.guildwars2.com/v2/continents/2/floors/1
$array = (new TestArrayClass(json_decode(file_get_contents(__DIR__.'/gw2api-floors-2-1.json'), true)));

$k = 'regions.7.maps.38.points_of_interest.990.name';

$this->assertSame('Stonemist Keep', $array->get($k));
$this->assertSame('Stonemist Keep', $array->search($k)); // RecursiveIterator

$this->assertNull($array->get($k.'.foo'));
$this->assertNull($array->search($k.'.foo')); // RecursiveIterator

$this->assertTrue($array->in($k));
$this->assertTrue($array->isset($k)); // RecursiveIterator

$this->assertFalse($array->in($k.'.foo'));
$this->assertFalse($array->isset($k.'.foo')); // RecursiveIterator

$array->set($k, 'foo');
$this->assertSame('foo', $array->get($k));

}
}
21 changes: 21 additions & 0 deletions tests/ArrayTrait/TestArrayClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php
/**
*
* @filesource TestArrayClass.php
* @created 30.12.2017
* @package chillerlan\TraitTest\ArrayTrait
* @author Smiley <[email protected]>
* @copyright 2017 Smiley
* @license MIT
*/

namespace chillerlan\TraitTest\ArrayTrait;

use chillerlan\Traits\ArrayHelpers\SearchableArray;

/**
* Class TestArrayClass
*/
class TestArrayClass{
use SearchableArray;
}
Loading

0 comments on commit 47a2dd7

Please sign in to comment.