Php Laravel collection多级分组方式插入新项目,无需检查每个级别';s键

Php Laravel collection多级分组方式插入新项目,无需检查每个级别';s键,php,laravel,collections,grouping,Php,Laravel,Collections,Grouping,Laravel collections现在内置了一个强大的多级groupBy功能,但我正在努力寻找一种插入新项目的合理方法 例如: $this->myCollection = EloquentModel::all()->groupBy(['key1','key2','key3','key4']); 非常好,易于设置和访问。对于本例,我将假设每个键都是一个数字 $this->myCollection[1][2][3][4] = new EloquentModel([insert

Laravel collections现在内置了一个强大的多级groupBy功能,但我正在努力寻找一种插入新项目的合理方法

例如:

$this->myCollection = EloquentModel::all()->groupBy(['key1','key2','key3','key4']);
非常好,易于设置和访问。对于本例,我将假设每个键都是一个数字

$this->myCollection[1][2][3][4] = new EloquentModel([insert => stuffHere]);
如果嵌套位置[1]、[2]和[3]中已存在项,则我可以在[4]添加新项或覆盖现有项,但如果缺少任何嵌套位置1到3,我将收到一个错误

Undefined offset: 1   (or 2 or 3 depending upon which is missing)
目前,我正在使用以下命令调用插入结构函数:

if (!$this->myCollection->has($1)) {
    $this->myCollection[$1] = new Collection;
}
if (!$this->myCollection[$1]->has($2)) {
    $this->myCollection[$1][$2] = new Collection;
}
if (!$this->myCollection[$1][$2]->has($3)) {
    $this->myCollection[$1][$2][$3] = new Collection;
}
$this->myCollection[$1][$2][$3][$4] = $itemFor4;
我发现groupBy嵌套非常有用,除了不能干净地处理插入内容之外

一些示例数据-请假设有>100k条记录,如下所示:

['username'=> 'a user name', 'course', => 'a coursename', 'activity_type' => 'one of 100s of activity names', 'reporting_week' => 23 // One of 52 weeks, [lots more data]]
['username'=> 'another user name', 'course', => 'another coursename', 'activity_type' => 'one of 100s of activity names', 'reporting_week' => 23 // One of 52 weeks, [lots more data]]
['username'=> 'a user name', 'course', => 'another coursename', 'activity_type' => 'one of 100s of activity names', 'reporting_week' => 24 // One of 52 weeks, [lots more data]]
['username'=> 'another user name', 'course', => 'a coursename', 'activity_type' => 'one of 100s of activity names', 'reporting_week' => 24 // One of 52 weeks, [lots more data]]

在现实生活中,它不是用户名和课程,而是表示特定用户和课程的代码

数据将包括活动分钟数、活动计数、活动等级、活动的早晚程度等。

我想您可以添加一个自定义的
insertDeep
函数

一个想法:

Collection::macro('insertDeep', function (array $path, $value) {
    $key = array_shift($path);
   
    if (count($path) === 0) {
        $this->put($key, $value);
        return $this;
    }

    if (!$this->has($key)) {
        $this->put($key, new Collection());
    }

    return $this->get($key)->insertDeep($path, $value);
});
然后,您可以简单地对集合调用此方法:

$this->myCollection->insertDeep([$1, $2, $3, $4], $itemFor4);
我刚试过,应该可以正常工作:

$coll = new Collection();
$coll->insertDeep(['a', 'b', 'c', 'd'], 'test');

$coll->toArray();
// Result
   [
     "a" => [
       "b" => [
         "c" => [
           "d" => "test",
         ],
       ],
     ],
   ]

免责声明:如果您指定一个路径,其中已存在一个键,但其值不是集合,则此函数将失败。

我认为空安全运算符将帮助您@Eklavya-您能否举例说明如何在分配数组/Laravel集合值时使用空安全运算符?@brianlmerritt您能否共享一些示例数据?您可以在这里详细阅读空安全运算符,我想您可以为
'key1'、'key2'、'key3'、'key4'
设置一个默认值,如果在groupBy之前它是空的,以确保键始终存在空安全运算符,这正是我想要的,除了我需要插入一个新的空集合以外