在 laravel 中合并两个集合

问题描述 投票:0回答:2

需要合并两个集合

我有两个集合,需要将它们合并为一个集合

这些集合是使用 Eloquent 的两个查询的输出

第一个结果如下:

Collection {#350
  #items: array:2 [
    0 => {#342
      +"id": 1
      +"code": "C000215"
      +"name": "Mostafa Mohamed Bayomi"
      +"mobile1": "01228902157"
      +"mobile2": ""
      +"CoachServiceCount": 0
      +"CourseServiceCount": 1
      +"CommunicationCount": 0
    }
    1 => {#337
      +"id": 2
      +"code": "C000216"
      +"name": "Sayed Mohamed Bayomi"
      +"mobile1": "01228902158"
      +"mobile2": ""
      +"CoachServiceCount": 0
      +"CourseServiceCount": 2
      +"CommunicationCount": 0
    }
]
}

第二次查询结果如下:

Collection {#350
  #items: array:2 [
    0 => {#346
      +"id": 1
      +"code": "C000215"
      +"name": "Mostafa Mohamed Bayomi"
      +"mobile1": "01228902157"
      +"mobile2": ""
      +"CoachServiceAmount": 0.0
    }
    1 => {#340
      +"id": 2
      +"code": "C000216"
      +"name": "Sayed Mohamed Bayomi"
      +"mobile1": "01228902158"
      +"mobile2": ""
      +"CoachServiceAmount": 0.0
    }
]
}

我使用此代码来合并两个集合

$combined = $firstCollection->merge($secondCollection)

我预计输出低于

Collection {#350
  #items: array:2 [
    0 => {#346
      +"id": 1
      +"code": "C000215"
      +"name": "Mostafa Mohamed Bayomi"
      +"mobile1": "01228902157"
      +"mobile2": ""
      +"CoachServiceCount": 0
      +"CourseServiceCount": 1
      +"CommunicationCount": 0
      +"CoachServiceAmount": 0.0
    }
    1 => {#340
      +"id": 2
      +"code": "C000216"
      +"name": "Sayed Mohamed Bayomi"
      +"mobile1": "01228902158"
      +"mobile2": ""
      +"CoachServiceCount": 0
      +"CourseServiceCount": 2
      +"CommunicationCount": 0
      +"CoachServiceAmount": 0.0
    }
]
}

但是我得到了这个输出

Collection {#350
  #items: array:4 [
    0 => {#342
      +"id": 1
      +"code": "C000215"
      +"name": "Mostafa Mohamed Bayomi"
      +"mobile1": "01228902157"
      +"mobile2": ""
      +"CoachServiceCount": 0
      +"CourseServiceCount": 1
      +"CommunicationCount": 0
    }
    1 => {#337
      +"id": 2
      +"code": "C000216"
      +"name": "Sayed Mohamed Bayomi"
      +"mobile1": "01228902158"
      +"mobile2": ""
      +"CoachServiceCount": 0
      +"CourseServiceCount": 2
      +"CommunicationCount": 0
    }
    2 => {#346
      +"id": 1
      +"code": "C000215"
      +"name": "Mostafa Mohamed Bayomi"
      +"mobile1": "01228902157"
      +"mobile2": ""
      +"CoachServiceAmount": 0.0
    }
    3 => {#340
      +"id": 2
      +"code": "C000216"
      +"name": "Sayed Mohamed Bayomi"
      +"mobile1": "01228902158"
      +"mobile2": ""
      +"CoachServiceAmount": 0.0
    }
  ]
}
php laravel-5 laravel-query-builder
2个回答
2
投票

问题

merge()的文档包含以下文本:

merge 方法将给定的数组或集合与原始集合合并。如果给定项目中的字符串键与原始集合中的字符串键匹配,则给定项目的值将覆盖原始集合中的值 (...) 如果给定项目的键是数字,则这些值将附加到合集结束

意思是

merge()
不会像你预期的那样工作,因为你使用的是数字键。

解决方案1:非数字键

解决您问题的一个解决方案是使用非数字值作为数组键,此解决方案仅在所选字段(示例中的

code
是主键)时才有效:

$firstCollection = $firstCollection->keyBy('code');
$secondCollection = $secondCollection->keyBy('code');
$combined = $firstCollection->merge($secondCollection);

// Optional: reset the array keys to be numeric
$combined = $combined->values();

keyBy 方法通过给定的键对集合进行键控。如果多个项目具有相同的键,则只有最后一个会出现在新集合中(source

values 方法返回一个新集合,其中键重置为连续整数(source

解决方案2:zip

如果两个集合中的元素数量相同且顺序相同,则可以这样做:

$combined = $firstCollection->zip($secondCollection);

zip 方法将给定数组的值与相应索引处的原始集合的值合并在一起(source


0
投票

使用

union
方法:https://laravel.com/docs/10.x/collections#method-union

union 方法将给定的数组添加到集合中。如果给定的数组包含原始集合中已有的键,则原始集合的值将是首选:

$collection = collect([1 => ['a'], 2 => ['b']]);
 
$union = $collection->union([3 => ['c'], 1 => ['d']]);
 
$union->all();
 
// [1 => ['a'], 2 => ['b'], 3 => ['c']]
© www.soinside.com 2019 - 2024. All rights reserved.