Skip to content

Commit f7adb61

Browse files
[10.x] Add data_remove helper (#47618)
* Add data_remove helper * Styleci * formatting --------- Co-authored-by: Taylor Otwell <[email protected]>
1 parent 6a2dff3 commit f7adb61

File tree

2 files changed

+125
-0
lines changed

2 files changed

+125
-0
lines changed

src/Illuminate/Collections/helpers.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,42 @@ function data_set(&$target, $key, $value, $overwrite = true)
149149
}
150150
}
151151

152+
if (! function_exists('data_forget')) {
153+
/**
154+
* Remove / unset an item from an array or object using "dot" notation.
155+
*
156+
* @param mixed $target
157+
* @param string|array|int|null $key
158+
* @return mixed
159+
*/
160+
function data_forget(&$target, $key)
161+
{
162+
$segments = is_array($key) ? $key : explode('.', $key);
163+
164+
if (($segment = array_shift($segments)) === '*' && Arr::accessible($target)) {
165+
if ($segments) {
166+
foreach ($target as &$inner) {
167+
data_forget($inner, $segments);
168+
}
169+
}
170+
} elseif (Arr::accessible($target)) {
171+
if ($segments && Arr::exists($target, $segment)) {
172+
data_forget($target[$segment], $segments);
173+
} else {
174+
Arr::forget($target, $segment);
175+
}
176+
} elseif (is_object($target)) {
177+
if ($segments && isset($target->{$segment})) {
178+
data_forget($target->{$segment}, $segments);
179+
} elseif (isset($target->{$segment})) {
180+
unset($target->{$segment});
181+
}
182+
}
183+
184+
return $target;
185+
}
186+
}
187+
152188
if (! function_exists('head')) {
153189
/**
154190
* Get the first element of an array. Useful for method chaining.

tests/Support/SupportHelpersTest.php

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,95 @@ public function testDataSetWithDoubleStar()
424424
], $data);
425425
}
426426

427+
public function testDataRemove()
428+
{
429+
$data = ['foo' => 'bar', 'hello' => 'world'];
430+
431+
$this->assertEquals(
432+
['hello' => 'world'],
433+
data_forget($data, 'foo')
434+
);
435+
436+
$data = ['foo' => 'bar', 'hello' => 'world'];
437+
438+
$this->assertEquals(
439+
['foo' => 'bar', 'hello' => 'world'],
440+
data_forget($data, 'nothing')
441+
);
442+
443+
$data = ['one' => ['two' => ['three' => 'hello', 'four' => ['five']]]];
444+
445+
$this->assertEquals(
446+
['one' => ['two' => ['four' => ['five']]]],
447+
data_forget($data, 'one.two.three')
448+
);
449+
}
450+
451+
public function testDataRemoveWithStar()
452+
{
453+
$data = [
454+
'article' => [
455+
'title' => 'Foo',
456+
'comments' => [
457+
['comment' => 'foo', 'name' => 'First'],
458+
['comment' => 'bar', 'name' => 'Second'],
459+
],
460+
],
461+
];
462+
463+
$this->assertEquals(
464+
[
465+
'article' => [
466+
'title' => 'Foo',
467+
'comments' => [
468+
['comment' => 'foo'],
469+
['comment' => 'bar'],
470+
],
471+
],
472+
],
473+
data_forget($data, 'article.comments.*.name')
474+
);
475+
}
476+
477+
public function testDataRemoveWithDoubleStar()
478+
{
479+
$data = [
480+
'posts' => [
481+
(object) [
482+
'comments' => [
483+
(object) ['name' => 'First', 'comment' => 'foo'],
484+
(object) ['name' => 'Second', 'comment' => 'bar'],
485+
],
486+
],
487+
(object) [
488+
'comments' => [
489+
(object) ['name' => 'Third', 'comment' => 'hello'],
490+
(object) ['name' => 'Fourth', 'comment' => 'world'],
491+
],
492+
],
493+
],
494+
];
495+
496+
data_forget($data, 'posts.*.comments.*.name');
497+
498+
$this->assertEquals([
499+
'posts' => [
500+
(object) [
501+
'comments' => [
502+
(object) ['comment' => 'foo'],
503+
(object) ['comment' => 'bar'],
504+
],
505+
],
506+
(object) [
507+
'comments' => [
508+
(object) ['comment' => 'hello'],
509+
(object) ['comment' => 'world'],
510+
],
511+
],
512+
],
513+
], $data);
514+
}
515+
427516
public function testHead()
428517
{
429518
$array = ['a', 'b', 'c'];

0 commit comments

Comments
 (0)