Laravel Collection的in_array替代方案:无需toArray()判断模型是否存在
不用
toArray()判断模型是否在集合中的实现方案 当然可以不用toArray()来搞定这个需求!Laravel的集合类本身就提供了非常方便的原生方法,完全不需要把模型实例转成数组来做对比,效率更高还更可靠。
下面给你几种实用的实现方式:
1. 直接用集合的contains()方法(最推荐)
这是最直接的解决方案,Laravel集合的contains()方法支持直接传入模型实例,它会自动通过模型的主键(比如默认的id字段)来判断是否存在于集合中:
if ($instance->contexts()->contains($context)) { // 这个$context实例已经在集合里啦 }
如果你的判断逻辑不是基于主键,还可以传闭包自定义匹配条件,比如对比多个字段:
if ($instance->contexts()->contains(function ($item) use ($context) { return $item->slug === $context->slug && $item->category_id === $context->category_id; })) { // 符合自定义条件的模型存在于集合中 }
2. 用find()方法快速查找
如果你已经知道目标模型的主键,也可以用集合的find()方法,它会返回匹配主键的模型实例,找不到就返回null,这样也能判断是否存在:
if ($instance->contexts()->find($context->id)) { // 模型存在于集合中 }
3. 封装成你想要的in_collection()函数
如果你确实想要像你伪代码里那样的自定义函数,完全可以自己封装一个,本质还是调用集合的原生方法:
function in_collection($targetModel, $collection) { return $collection->contains($targetModel); } // 调用方式和你期望的伪代码完全一致 if (in_collection($context, $instance->contexts())) { // 模型存在 }
为什么不推荐原来的toArray()方式?
把模型转成数组会带来几个问题:
- 额外的性能消耗:模型转数组需要处理字段、关联、隐藏属性等逻辑,完全没必要做这个额外操作
- 判断不准确:如果模型有隐藏字段(比如
$hidden属性里的字段),转数组后这些字段会丢失,可能导致本该匹配的模型不匹配 - 代码冗余:明明有原生方法可以直接用,转数组属于多此一举
内容的提问来源于stack exchange,提问作者Ivan T.
相关产品推荐
相关产品推荐

