如何在获取元素后取消设置(删除)集合元素?


79

我有一个集合,在获取某些元素时要进行迭代和修改。但是我找不到删除该获取的元素的方法或方法。

$selected = []; 
foreach ($collection as $key => $value) {
      if ($collection->selected == true) {
          $selected[] = $value;
          unset($value);
      }
}

这只是我要示范的问题的代表。

@Ohgodwhy提出了got()函数的建议后,我再次对其进行了检查,发现我实际上对该函数有误解。正是我想要的。

因此,对于有效的解决方案,我$collection->forget($key)在if语句中添加了内容。

下面是使用@Ohgodwhy的解决方案解决我的问题的方法:

$selected = []; 
foreach ($collection as $key => $value) {
      if ($collection->selected == true) {
          $selected[] = $value;
          $collection->forget($key);
      }
}

(这只是一个演示)


1
我建议不要将您的项目存储在数组中,而是创建一个新的集合并通过推送将元素添加到其中。
Amarnasan

@Amarnasan将如何处理?我并不需要它,但现在我想我可能需要在未来的
查理

在这里看看:stackoverflow.com/a/58769554/655224。你的if情况$collection->selected == true没有道理。为什么要检查对象的属性selectedcollection不是value?如果该属性确实在内部collection,则在循环外部对其进行一次检查。
algorhythm

Answers:


124

您想使用 ->forget()

$collection->forget($key);

链接到忘记方法文档


1
是的,实际上我误会了got()。我认为$ key参数会删除所有给定的键。现在,我可以通过if语句在循环中使用它。
Skeletor

18
forget()相比delete()remove(),这是很酷的,但是地狱,我不得不
来这里找

如果要删除整个对象怎么办?
Chaudhry Waqas '18

5
@Adamnickforget您需要知道index数组中对象的。您想要的可能是filter()
Ohgodwhy,

对于现在正在查看此内容的任何人,原始问题中的链接都已断开,但您可以在这里找到相同的文档laravel.com/docs/5.8/collections#method-forget
Bryce Meyer

25

或者你可以使用reject 方法

$newColection = $collection->reject(function($element) {
    return $item->selected != true;
});

pull 方法

$selected = []; 
foreach ($collection as $key => $item) {
      if ($item->selected == true) {
          $selected[] = $collection->pull($key);
      }
}

1
但是拒绝解决方案不会从原始集合中删除元素,对吗?
Amarnasan

是的,它保持了原始收藏的完整性
huuuk

1
那么,该问题的完美解决方案将是第二个。
Amarnasan

$collection = $collection->reject(...)将使用新集合覆盖原始集合。这$collection->pull(...)是我认为的最佳解决方案。主题标题包含...after fetching it...。那是什么pull
algorhythm

13

LaravelCollection实现了PHPArrayAccess接口(这就是为什么foreach首先可以使用的原因)。

如果已经有了密钥,则可以使用PHP unset

我更喜欢这样做,因为它可以明显地修改集合,并且易于记忆。

foreach ($collection as $key => $value) {
    unset($collection[$key]);
}

2

我对遍历一个集合并在循环内甚至操纵该集合的内容的解决方案都不满意。这可能会导致意外的行为。

另请参见此处:https//stackoverflow.com/a/2304578/655224,并在注释中提供了给定的链接http://php.net/manual/en/control-structures.foreach.php#88578

因此,当使用foreachif似乎可以但恕我直言时,更具可读性和简单性的解决方案是将您的馆藏过滤为新馆藏。

/**
 * Filter all `selected` items
 *
 * @link https://laravel.com/docs/7.x/collections#method-filter
 */
$selected = $collection->filter(function($value, $key) {
    return $value->selected;
})->toArray();

0

如果您知道未设置的密钥,则直接用逗号分隔

unset($attr['placeholder'], $attr['autocomplete']);

我有一个特殊情况,我有一个物品清单系统,其中一个新属性在最新的属性集合中以及未评级的集合中返回,这些属性都显示在一页上。我希望已经在第一个列表中的那些项目从第二个lisg中弹出,我该怎么做。请记住,您不能告诉该项目将出现在索引中。我可以做类似的事情$collection->forget($item->id) 吗?
软件开发人员
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.