Skip to content

Commit 3178e1e

Browse files
committed
Add array_set and Arr::set functionality
1 parent dd0bed6 commit 3178e1e

File tree

3 files changed

+117
-0
lines changed

3 files changed

+117
-0
lines changed

src/Arr.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,34 @@ public static function has(array $array, $key)
6464

6565
return true;
6666
}
67+
68+
/**
69+
* Set an array item to a given value using "dot" notation.
70+
*
71+
* @param array $array
72+
* @param string $key
73+
* @param mixed $value
74+
* @return array
75+
*/
76+
public static function set(&$array, $key, $value)
77+
{
78+
$keys = explode('.', $key);
79+
80+
while (count($keys) > 1) {
81+
$key = array_shift($keys);
82+
83+
// If the key doesn't exist at this depth, we will just create an empty array
84+
// to hold the next value, allowing us to create the arrays to hold final
85+
// values at the correct depth. Then we'll keep digging into the array.
86+
if (! isset($array[$key]) || ! is_array($array[$key])) {
87+
$array[$key] = [];
88+
}
89+
90+
$array = &$array[$key];
91+
}
92+
93+
$array[array_shift($keys)] = $value;
94+
95+
return $array;
96+
}
6797
}

src/array-helpers.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,8 @@ function array_has($array, $key)
1111
{
1212
return Arr::has($array, $key);
1313
}
14+
15+
function array_set(&$array, $key, $value)
16+
{
17+
return Arr::set($array, $key, $value);
18+
}

tests/ArraySetTest.php

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
3+
namespace ArrayHelpers;
4+
5+
use PHPUnit\Framework\TestCase;
6+
7+
class ArraySetTest extends TestCase
8+
{
9+
public function testWillSetSingleValue()
10+
{
11+
$expected = ['rolling' => 'stones'];
12+
13+
$initial = [];
14+
Arr::set($initial, 'rolling', 'stones');
15+
$this->assertEquals($expected, $initial);
16+
17+
$initial = [];
18+
array_set($initial, 'rolling', 'stones');
19+
$this->assertEquals($expected, $initial);
20+
}
21+
22+
public function testWillOverwriteExistingValue()
23+
{
24+
$initial = ['rolling' => 'stones'];
25+
Arr::set($initial, 'rolling', 'thunder');
26+
$this->assertEquals(
27+
['rolling' => 'thunder'],
28+
$initial
29+
);
30+
}
31+
32+
public function testWillSetUsingDotNotation()
33+
{
34+
$initial = [];
35+
Arr::set($initial, "i.can't.get.no", 'satisfaction');
36+
$this->assertEquals(
37+
[
38+
'i' => [
39+
"can't" => [
40+
'get' => [
41+
'no' => 'satisfaction',
42+
],
43+
],
44+
],
45+
],
46+
$initial
47+
);
48+
}
49+
50+
public function testWillOnlyPartiallyOverwriteUsingDotNotation()
51+
{
52+
$initial = [
53+
'i' => [
54+
"can't" => [
55+
'live' => [
56+
'in' => [
57+
'a' => 'living room',
58+
]
59+
]
60+
]
61+
]
62+
];
63+
Arr::set($initial, "i.can't.get.no", 'satisfaction');
64+
$this->assertEquals(
65+
[
66+
'i' => [
67+
"can't" => [
68+
'live' => [
69+
'in' => [
70+
'a' => 'living room',
71+
],
72+
],
73+
'get' => [
74+
'no' => 'satisfaction',
75+
],
76+
],
77+
],
78+
],
79+
$initial
80+
);
81+
}
82+
}

0 commit comments

Comments
 (0)