【问题标题】:Laravel collection multi level groupBy insert new items without checking each level's keyLaravel 集合多级组通过插入新项目而不检查每个级别的键
【发布时间】:2021-05-31 20:07:29
【问题描述】:

Laravel 集合现在内置了一个很棒的多级 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 嵌套非常有用,除了不能干净地处理我的插入。

一些示例数据 - 请假设有 > 10 万条这样的记录:

['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]]

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

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

【问题讨论】:

  • 我认为 null 安全运算符会帮助你wiki.php.net/rfc/nullsafe_operator
  • @Eklavya - 你能举例说明在分配数组/Laravel 集合值时如何使用 null 安全运算符吗?
  • @brianlmerritt 你能分享一些示例数据吗?您可以在此处详细了解空安全运算符Null Safe Operator
  • 如果'key1','key2','key3','key4'在groupBy之前为空,我认为你可以设置一个默认值,以确保key始终存在
  • 关于 null 安全运算符,这正是我想要的,除了我需要插入一个新的空集合而不是 null

标签: php laravel collections grouping


【解决方案1】:

我认为你可以extend the collection,添加自定义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",
         ],
       ],
     ],
   ]

免责声明:如果您指定一个键已经存在但其值不是集合的路径,则此功能将失败

【讨论】:

    猜你喜欢
    • 2017-02-05
    • 2022-11-10
    • 2019-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-04
    • 2017-02-07
    • 2021-11-20
    相关资源
    最近更新 更多