|
3 | 3 | namespace Sarhan\Flatten; |
4 | 4 |
|
5 | 5 | /** |
6 | | - * @author Alaa Sarhan <sarhan.alaa@gmail.com> |
7 | | - * @license LGPL |
| 6 | + * Flattens values, possibly traversables, into a one-dimensional array, recursively. |
8 | 7 | */ |
9 | 8 | class Flatten |
10 | 9 | { |
| 10 | + const DEFAULT_SEPARATOR = '.'; |
| 11 | + const DEFAULT_PREFIX = ''; |
| 12 | + const DEFAULT_FLAGS = 0; |
| 13 | + |
11 | 14 | /** |
12 | 15 | * Turn off flattening values with integer keys. |
13 | 16 | */ |
14 | 17 | const FLAG_NUMERIC_NOT_FLATTENED = 0b1; |
| 18 | + |
| 19 | + /** |
| 20 | + * @var string $separator |
| 21 | + */ |
| 22 | + private $separator; |
| 23 | + |
| 24 | + /** |
| 25 | + * @var string $prefix |
| 26 | + */ |
| 27 | + private $prefix; |
| 28 | + |
| 29 | + /** |
| 30 | + * @var int $flags |
| 31 | + */ |
| 32 | + private $flags; |
| 33 | + |
| 34 | + /** |
| 35 | + * @param string $separator |
| 36 | + * @param string $prefix |
| 37 | + * @param int $flags |
| 38 | + * @return Flatten |
| 39 | + * @see Flatten::FLAG_NUMERIC_NOT_FLATTENED |
| 40 | + */ |
| 41 | + public function __construct( |
| 42 | + $separator = self::DEFAULT_SEPARATOR, |
| 43 | + $prefix = self::DEFAULT_PREFIX, |
| 44 | + $flags = self::DEFAULT_FLAGS |
| 45 | + ) { |
| 46 | + $this->separator = $separator; |
| 47 | + $this->prefix = $prefix; |
| 48 | + $this->flags = $flags; |
| 49 | + } |
15 | 50 |
|
16 | 51 | /** |
17 | | - * Flattens a variable, possibly traversable, into a one-dimensional array, recursively. |
| 52 | + * Flattens a traversable or array into a 1-dimensional array. |
18 | 53 | * |
19 | 54 | * Each key (fully-qualified key or FQK) in the returned one-dimensional array is the join of all keys leading to |
20 | | - * each (non-traversable) value, in all dimensions, separated by a given separator. |
| 55 | + * each (non-traversable) value, in all dimensions, separated by the configured separator. |
21 | 56 | * |
22 | | - * An initial prefix can be optionally provided, but it will not be separated with the specified separator. |
| 57 | + * The configured prefix will be appended to all FQKs, but it will not be separated with the configured separator. |
23 | 58 | * |
24 | 59 | * @param mixed $var |
25 | | - * @param string $separator |
26 | | - * @param string $prefix |
27 | | - * @param int $flags |
28 | 60 | * @return array 1-dimensional array containing all values from all possible traversable dimensions in given input. |
29 | | - * @see Flatten::FLAG_NUMERIC_NOT_FLATTENED |
30 | 61 | */ |
31 | | - public static function flatten($var, $separator = '.', $prefix = '', $flags = 0) |
| 62 | + public function flatten($var) |
32 | 63 | { |
33 | | - $flattened = []; |
34 | | - foreach (self::flattenGenerator($var, $separator, '', $flags) as $key => $value) { |
35 | | - $flattened[$prefix . $key] = $value; |
| 64 | + foreach ($this->flattenGenerator($var, $this->separator, '', $this->flags) as $key => $value) { |
| 65 | + yield ($this->prefix . $key) => $value; |
36 | 66 | } |
37 | | - return $flattened; |
38 | 67 | } |
39 | 68 |
|
40 | | - private static function flattenGenerator($var, $separator, $prefix = '', $flags = 0) |
| 69 | + private function flattenGenerator($var, $separator, $prefix = '', $flags = 0) |
41 | 70 | { |
42 | | - if (!self::canTraverse($var)) { |
| 71 | + if (!$this->canTraverse($var)) { |
43 | 72 | yield $prefix => $var; |
44 | 73 | return; |
45 | 74 | } |
46 | 75 |
|
47 | 76 | if ($flags & self::FLAG_NUMERIC_NOT_FLATTENED) { |
48 | | - list ($values, $var) = self::filterNumericKeysAndGetValues($var); |
| 77 | + list ($values, $var) = $this->filterNumericKeysAndGetValues($var); |
49 | 78 | if (!empty($values) || empty($var)) { |
50 | 79 | yield $prefix => $values; |
51 | 80 | } |
52 | 81 | } |
53 | 82 |
|
54 | 83 | $prefix .= (empty($prefix) ? '' : $separator); |
55 | 84 | foreach ($var as $key => $value) { |
56 | | - foreach (self::flattenGenerator($value, $separator, $prefix . $key, $flags) as $k => $v) { |
| 85 | + foreach ($this->flattenGenerator($value, $separator, $prefix . $key, $flags) as $k => $v) { |
57 | 86 | yield $k => $v; |
58 | 87 | } |
59 | 88 | } |
60 | 89 | } |
61 | 90 |
|
62 | | - private static function canTraverse($var) |
| 91 | + private function canTraverse($var) |
63 | 92 | { |
64 | 93 | return is_array($var) || ($var instanceof \Traversable); |
65 | 94 | } |
66 | 95 |
|
67 | | - private static function filterNumericKeysAndGetValues($var) |
| 96 | + private function filterNumericKeysAndGetValues($var) |
68 | 97 | { |
69 | 98 | $values = []; |
70 | 99 | $var = array_filter($var, function ($value, $key) use (&$values) { |
|
0 commit comments