Passed
Push — master ( 259c4a...d70309 )
by Shane
13:37
created

Arr::swapKeysFn()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 29
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 5

Importance

Changes 0
Metric Value
eloc 15
c 0
b 0
f 0
dl 0
loc 29
rs 9.4555
ccs 7
cts 7
cp 1
cc 5
nc 4
nop 3
crap 5
1
<?php
2
3
namespace ElegantMedia\PHPToolkit;
4
5
class Arr
6
{
7
8
9
	/**
10
	 *
11
	 * Is the array an associative array?
12
	 *
13
	 * @param $input
14
	 *
15
	 * @return bool
16
	 */
17 27
	public static function isAssoc($input): bool
18
	{
19 27
		if (!is_array($input)) {
20 3
			return false;
21
		}
22 24
		return array_keys($input) !== range(0, count($input) - 1);
23
	}
24
25
26
	/**
27
	 *
28
	 * Find matching structure on a nested array recursively
29
	 *
30
	 * @param       $subset
31
	 * @param       $array
32
	 * @param array $results
33
	 *
34
	 * @return array
35
	 */
36 21
	public static function intersectRecursive($array, $subset, $results = []): array
37
	{
38 21
		$isAssocArray = self::isAssoc($subset);
39
40 21
		if ($isAssocArray) {
41
			// loop each row of array
42
			// iterating through parents
43 12
			foreach ($subset as $key => $value) {
44 12
				if ($key) {
45 12
					if (isset($array[$key])) {
46 12
						$filteredSource = $array[$key];
47
48
						//if the value is array, it will do the recursive
49 12
						if (is_array($value)) {
50 12
							$loopResults = self::intersectRecursive($filteredSource, $subset[$key], $results);
51 12
							$results[$key] = $loopResults;
52
						}
53
					}
54
				}
55
			}
56
		} else {
57
			// iterate through final leaf nodes
58 21
			foreach ($subset as $subsetRow) {
59 21
				foreach ($array as $sourceRow) {
60 21
					$subsetRow = self::removeChildArrays($subsetRow);
61 21
					$sourceRow = self::removeChildArrays($sourceRow);
62 21
					if (array_intersect($subsetRow, $sourceRow) == $subsetRow) {
63 18
						$results[] = $subsetRow;
64
					}
65
				}
66
			}
67
		}
68
69 21
		return $results;
70
	}
71
72
73 21
	public static function removeChildArrays($array): array
74
	{
75 21
		$response = [];
76 21
		foreach ($array as $key => $value) {
77 21
			if (is_array($value)) {
78 3
				$response[$key] = json_encode($value);
79
			} else {
80 21
				$response[$key] = $value;
81
			}
82
		}
83 21
		return $response;
84
	}
85
86
	/**
87
	 *
88
	 * Implode but don't include empty values
89
	 *
90
	 * @param $glue
91
	 * @param $pieces
92
	 *
93
	 * @return string
94
	 */
95 3
	public static function implodeIgnoreEmpty($glue, $pieces): string
96
	{
97
		// remove empty values
98 3
		$pieces = array_filter($pieces);
99
100 3
		return implode($glue, $pieces);
101
	}
102
103
	/**
104
	 *
105
	 * Replace an existing key of an array with a new one, recursively if required.
106
	 *
107
	 * @param array $array
108
	 * @param $existingKey
109
	 * @param $newKey
110
	 * @param false $recursive
111
	 * @return array
112
	 */
113 6
	public static function swapKey(array $array, $existingKey, $newKey, $recursive = false): array
114
	{
115 6
		$allArrayData = [];
116 6
		foreach ($array as $item) {
117 6
			$arrayData = $item;
118 6
			if (array_key_exists($existingKey, $arrayData)) {
119 6
				$arrayData[$newKey] = $arrayData[$existingKey];
120 6
				unset($arrayData[$existingKey]);
121
			}
122
123
			// do this recursively
124 6
			if ($recursive) {
125 3
				if (isset($arrayData[$newKey]) && count($arrayData[$newKey])) {
126 3
					$arrayData[$newKey] = self::swapKey($arrayData[$newKey], $existingKey, $newKey, true);
127
				}
128
			}
129
130 6
			$allArrayData[] = $arrayData;
131
		}
132 6
		return $allArrayData;
133
	}
134
135
	/**
136
	 * Replace keys of a given array based on a given function
137
	 * Based on http://stackoverflow.com/questions/1444484/how-to-convert-all-keys-in-a-multi-dimenional-array-to-snake-case
138
	 *
139
	 * @param mixed $mixed
140
	 * @param callable $keyReplaceFunction
141
	 * @param bool|true $recursive
142
	 */
143
	public static function swapKeysFn(&$mixed, callable $keyReplaceFunction, $recursive = true): void
144
	{
145
		if (is_array($mixed))
146
		{
147
			foreach (array_keys($mixed) as $key):
148
				# Working with references here to avoid copying the value,
149
				# Since input data can be large
150
				$value = &$mixed[$key];
151
				unset($mixed[$key]);
152
153
				#  - camelCase to snake_case
154
				$transformedKey = $keyReplaceFunction($key);
155
156
				# Work recursively
157 3
				if ($recursive && is_array($value)) array_keys_replace($value, $keyReplaceFunction, $recursive);
0 ignored issues
show
Bug introduced by
The function array_keys_replace was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

157
				if ($recursive && is_array($value)) /** @scrutinizer ignore-call */ array_keys_replace($value, $keyReplaceFunction, $recursive);
Loading history...
158
159 3
				# Store with new key
160
				$mixed[$transformedKey] = $value;
161 3
				# Do not forget to unset references!
162 3
				unset($value);
163 3
			endforeach;
164 3
		}
165
		else
166
		{
167
			$newVal = preg_replace('/[A-Z]/', '_$0', $mixed);
168
			$newVal = strtolower($newVal);
169 3
			$newVal = ltrim($newVal, '_');
170
			$mixed = $newVal;
171
			unset($newVal);
172
		}
173
	}
174
175
176
	/**
177
	 *
178
	 * Get an array and key it by a given key
179
	 * @example
180
	 * [
181
	 *        [ 'name' => 'john', 'age' => 45 ],
182
	 *        [ 'name' => 'jane', 'age', => 32 ],
183
	 * ]
184
	 * $people = Arr::keyBy($rows, 'name');
185
	 *
186
	 * becomes
187
	 * [
188
	 *        'john' => [ 'age' => 45 ],
189
	 *        'jane' => [ 'age' => 32 ],
190
	 * ]
191
	 *
192
	 *
193
	 * @param $array
194
	 * @param $keyBy
195
	 *
196
	 * @return array
197
	 */
198
	public static function keyBy($array, $keyBy): array
199
	{
200
		$newValues = [];
201
202
		foreach ($array as $key => $value) {
203
			if (is_array($value)) {
204
				if (isset($value[$keyBy]) && $value[$keyBy] !== '') {
205
					$newValues[$value[$keyBy]][] = $value;
206
				}
207
			}
208
		}
209
210
		return $newValues;
211
	}
212
}
213