如何在Laravel的Collection集合中访问指定元素并获取其对应键名
解决方案
你原有代码存在3个核心问题:
search方法使用错误:该方法匹配成功时默认返回对应元素的索引键,而非元素本身,且默认松散比较对对象匹配极易失效- 循环变量名冲突:内层
foreach的键名也使用了$key,会直接覆盖外层循环的键变量 - 未做匹配失败的边界处理:如果没找到对应元素直接操作会抛出错误
方案1:修正search方法用法
如果你两次获取的后代是同一个对象实例,只需要修正search的参数和变量赋值即可:
$descendants = $root->getDescendants(); foreach ($descendants as $parentKey => &$item) { $itemDescendants = $item->getDescendants(); // 内层循环不要和外层用同名的$key变量 foreach ($itemDescendants as $subKey => &$childItem) { // 加第二个参数true做严格对象匹配,返回值就是对应索引$childKey $childKey = $descendants->search($childItem, true); // 匹配不到就跳过,避免报错 if ($childKey === false) { continue; } $user_permissions = []; if(!empty($descendants[$childKey]->permissions)){ $permissions = $descendants[$childKey]->permissions; } // 注意你原代码中的$contentPermission要确保作用域正常可访问 $user_permissions['all'] = ($user_permissions['all'] !== 0) ? $contentPermission['all'] : $user_permissions['all']; $user_permissions['view'] = ($user_permissions['view'] !== 0) ? $contentPermission['view'] : $user_permissions['view']; $descendants[$childKey]->user_permissions = $user_permissions; } } return $descendants;
方案2:主键索引法(更稳定,推荐)
如果两次getDescendants返回的是不同的对象实例(比如重复查了数据库),用search匹配不到,直接用模型主键做索引是最稳妥的方案:
// 先用keyBy方法把集合按主键id重新索引,后续查找复杂度为O(1),比search效率高很多 $descendants = $root->getDescendants()->keyBy('id'); foreach ($descendants as $parentId => &$item) { $itemDescendants = $item->getDescendants(); foreach ($itemDescendants as $subKey => &$childItem) { // 直接用子项id查找,不需要遍历匹配 if (!isset($descendants[$childItem->id])) { continue; } $user_permissions = []; if(!empty($descendants[$childItem->id]->permissions)){ $permissions = $descendants[$childItem->id]->permissions; } $user_permissions['all'] = ($user_permissions['all'] !== 0) ? $contentPermission['all'] : $user_permissions['all']; $user_permissions['view'] = ($user_permissions['view'] !== 0) ? $contentPermission['view'] : $user_permissions['view']; $descendants[$childItem->id]->user_permissions = $user_permissions; } } // 如果你需要返回的集合是原数字索引格式,调用values()重置索引即可 return $descendants->values();
内容的提问来源于stack exchange,提问作者SubjectX
相关产品推荐
相关产品推荐

