Php 如何基于键合并Laravel集合的项?
我有一个Laravel系列,其中有许多重复的项目,如:Php 如何基于键合并Laravel集合的项?,php,laravel,collections,Php,Laravel,Collections,我有一个Laravel系列,其中有许多重复的项目,如: [ id: 'NAME1', prop1: 'yes', prop2: null, prop3: 'bla', prop4: null ], [ id: 'NAME1', prop1: null, prop2: 'yes' prop3: null, prop4: 'bla' ] 我想合并具有相同“id”属性的元素,并得到这样一个集合,同时保留这两个属性: [ id: 'NAME1', pro
[
id: 'NAME1',
prop1: 'yes',
prop2: null,
prop3: 'bla',
prop4: null
],
[
id: 'NAME1',
prop1: null,
prop2: 'yes'
prop3: null,
prop4: 'bla'
]
我想合并具有相同“id”属性的元素,并得到这样一个集合,同时保留这两个属性:
[
id: 'NAME1',
prop1: 'yes',
prop2: 'yes',
prop3: 'bla',
prop4: 'bla'
]
当我使用$collection->unique('id')
时,我只得到这样一个集合,失去了
第二个要素:
[
id: 'NAME1',
prop1: 'yes',
prop2: null,
prop3: 'bla',
prop4: null
]
我怎样才能解决它?我找不到任何Laravel集合的方法,当其中一个元素具有空键时,该方法可以合并集合的元素。因此,您希望合并每个id的所有非空属性(列表中只有一个id,但我假设可能有多个id) 1) 按id分组并获取[id=>[id的所有属性列表]] 2) 对于每个id: 2a)从每个列表中删除空属性 2b)将所有列表合并为一个 使用laravel系列可以通过以下方式实现:
$data = '[
{
"id": "NAME1",
"prop1": "yes",
"prop2": null,
"prop3": "bla",
"prop4": null
},
{
"id": "NAME1",
"prop1": null,
"prop2": "yes",
"prop3": null,
"prop4": "bla"
},
{
"id": "NAME2",
"prop1": "no",
"prop2": "dah",
"prop4": "bla"
}
]
';
$coll = collect(json_decode($data, JSON_OBJECT_AS_ARRAY))
->groupBy('id')
->map(function ($propGroup) {
//for each group of 'objects' of property lists
return $propGroup
->map(function ($props) {
//remove empty properties
return collect($props)->filter(function ($prop) {
return !empty($prop);
});
})
->reduce(function ($carry, $item) {
return $carry->merge($item);
}, collect());
});
下面是一个宏,它将执行您想要的操作:
使用light\Support\Collection;
集合::宏('mergeByKey',函数($key){
返回$this->groupBy($key)->map(函数($group){
$filteredGroup=collect($group)->map(函数($item){
返回-收集($item)->拒绝(函数($value,$key){
返回$value==null;
});
});
返回数组合并(…$filteredGroup->toArray());
})->值();
});
然后,您可以在这样的集合中使用它:
$collection=collect([
[
'id'=>'NAME1',
“prop1”=>“是”,
'prop2'=>null,
“prop3”=>“bla”,
'prop4'=>null
],
[
'id'=>'NAME1',
'prop1'=>null,
“prop2”=>“是”,
'prop3'=>null,
“prop4”=>“bla”
],
[
'id'=>'NAME2',
'prop1'=>null,
'prop2'=>'fdsa',
'prop3'=>null,
“prop4”=>“asdf”
],
[
'id'=>'NAME2',
“prop1”=>“fdsa”,
'prop2'=>null,
“prop3”=>“asdf”,
'prop4'=>null
],
]);
$result=$collection->mergeByKey('id');
结果:
Collection {#268 ▼
#items: array:2 [▼
0 => array:5 [▼
"id" => "NAME1"
"prop1" => "yes"
"prop3" => "bla"
"prop2" => "yes"
"prop4" => "bla"
]
1 => array:5 [▼
"id" => "NAME2"
"prop2" => "fdsa"
"prop4" => "asdf"
"prop1" => "fdsa"
"prop3" => "asdf"
]
]
}
我认为集合上没有解决这个问题的函数。您可能需要编写自己的函数。你可以
array\u遍历集合并比较数组。因此,如果不迭代所有元素,就无法做到这一点?我当然无法想象其他任何方法。您需要遍历第一个集合,并从中构建一个结果集合,检查字段以填充非空值。而且,如果遇到多个非唯一值,您还必须决定如何处理。。。例如,在OP中,如果第一条记录的(say)prop1
是(say)“no.”
那么,您自己设计的算法,适合您的目的。