Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何基于键合并Laravel集合的项?_Php_Laravel_Collections - Fatal编程技术网

Php 如何基于键合并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

我有一个Laravel系列,其中有许多重复的项目,如:

[
  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.”
那么,您自己设计的算法,适合您的目的。