Skip to content

Commit b6d6ce0

Browse files
committed
feat: Add array helper intersectKeyRecursive
1 parent 1d175df commit b6d6ce0

File tree

2 files changed

+211
-0
lines changed

2 files changed

+211
-0
lines changed

system/Helpers/Array/ArrayHelper.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,4 +315,27 @@ public static function sortValuesByNatural(array &$array, $sortByIndex = null):
315315
return strnatcmp((string) $currentValue, (string) $nextValue);
316316
});
317317
}
318+
319+
/**
320+
* Returns a new array from $target with the keys that are in $original
321+
*
322+
* @param array<string, array<string,mixed>|string|null> $target
323+
* @param array<string, array<string,mixed>|string|null> $original
324+
*
325+
* @return array<string, array<string,mixed>|string|null>
326+
*/
327+
public static function intersectKeyRecursive(array $target, array $original): array
328+
{
329+
$result = [];
330+
331+
foreach ($target as $key => $value) {
332+
if (is_array($value) && isset($original[$key]) && is_array($original[$key])) {
333+
$result[$key] = self::intersectKeyRecursive($value, $original[$key]);
334+
} elseif (array_key_exists($key, $original)) {
335+
$result[$key] = $value;
336+
}
337+
}
338+
339+
return $result;
340+
}
318341
}
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of CodeIgniter 4 framework.
7+
*
8+
* (c) CodeIgniter Foundation <[email protected]>
9+
*
10+
* For the full copyright and license information, please view
11+
* the LICENSE file that was distributed with this source code.
12+
*/
13+
14+
namespace CodeIgniter\Helpers\Array;
15+
16+
use CodeIgniter\Test\CIUnitTestCase;
17+
use PHPUnit\Framework\Attributes\Group;
18+
19+
/**
20+
* @internal
21+
*/
22+
#[Group('Others')]
23+
final class ArrayHelperIntersectKeyRecursiveTest extends CIUnitTestCase
24+
{
25+
/**
26+
* @var array<string, array<string,mixed>|string|null>
27+
*/
28+
private array $targetArray;
29+
30+
protected function setUp(): void
31+
{
32+
parent::setUp();
33+
34+
$this->targetArray = [
35+
'a' => [
36+
'b' => [
37+
'c' => [
38+
'd' => 'value1',
39+
],
40+
],
41+
'e' => 'value2',
42+
'f' => [
43+
'g' => 'value3',
44+
'h' => 'value4',
45+
'i' => [
46+
'j' => 'value5',
47+
],
48+
],
49+
'k' => null,
50+
'l' => [],
51+
'm' => '',
52+
],
53+
];
54+
}
55+
56+
public function testShuffleCopy(): void
57+
{
58+
$original = [
59+
'a' => [
60+
'l' => [],
61+
'k' => null,
62+
'e' => 'value2',
63+
'f' => [
64+
'i' => [
65+
'j' => 'value5',
66+
],
67+
'h' => 'value4',
68+
'g' => 'value3',
69+
],
70+
'm' => '',
71+
'b' => [
72+
'c' => [
73+
'd' => 'value1',
74+
],
75+
],
76+
],
77+
];
78+
79+
// var_dump(ArrayHelper::intersectKeyRecursive($original, $this->targetArray));
80+
81+
$this->assertSame($original, ArrayHelper::intersectKeyRecursive($original, $this->targetArray));
82+
}
83+
84+
public function testCopyWithAnotherValues(): void
85+
{
86+
$original = [
87+
'a' => [
88+
'b' => [
89+
'c' => [
90+
'd' => 'value1_1',
91+
],
92+
],
93+
'e' => 'value2_2',
94+
'f' => [
95+
'g' => 'value3_3',
96+
'h' => 'value4_4',
97+
'i' => [
98+
'j' => 'value5_5',
99+
],
100+
],
101+
'k' => [],
102+
'l' => null,
103+
'm' => 'value6_6',
104+
],
105+
];
106+
107+
$this->assertSame($original, ArrayHelper::intersectKeyRecursive($original, $this->targetArray));
108+
}
109+
110+
public function testEmptyCompare(): void
111+
{
112+
$this->assertSame([], ArrayHelper::intersectKeyRecursive($this->targetArray, []));
113+
}
114+
115+
public function testEmptyOriginal(): void
116+
{
117+
$this->assertSame([], ArrayHelper::intersectKeyRecursive([], $this->targetArray));
118+
}
119+
120+
public function testCompletelyDifferent(): void
121+
{
122+
$original = [
123+
'new_a' => [
124+
'new_b' => [
125+
'new_c' => [
126+
'new_d' => 'value1_1',
127+
],
128+
],
129+
'new_e' => 'value2_2',
130+
'new_f' => [
131+
'new_g' => 'value3_3',
132+
'new_h' => 'value4_4',
133+
'new_i' => [
134+
'new_j' => 'value5_5',
135+
],
136+
],
137+
'new_k' => [],
138+
'new_l' => null,
139+
'new_m' => '',
140+
],
141+
];
142+
143+
$this->assertSame([], ArrayHelper::intersectKeyRecursive($original, $this->targetArray));
144+
}
145+
146+
public function testRecursiveDiffPartlyDifferent(): void
147+
{
148+
$original = [
149+
'a' => [
150+
'b' => [
151+
'new_c' => [
152+
'd' => 'value1',
153+
],
154+
],
155+
'e' => 'value2',
156+
'f' => [
157+
'g' => 'value3',
158+
'new_h' => 'value4',
159+
'i' => [
160+
'new_j' => 'value5',
161+
],
162+
],
163+
'k' => null,
164+
'new_l' => [],
165+
'm' => [
166+
'new_n' => '',
167+
],
168+
],
169+
];
170+
171+
$intersect = [
172+
'a' => [
173+
'b' => [],
174+
'e' => 'value2',
175+
'f' => [
176+
'g' => 'value3',
177+
'i' => [],
178+
],
179+
'k' => null,
180+
'm' => [
181+
'new_n' => '',
182+
],
183+
],
184+
];
185+
186+
$this->assertSame($intersect, ArrayHelper::intersectKeyRecursive($original, $this->targetArray));
187+
}
188+
}

0 commit comments

Comments
 (0)