php - 复杂的 Laravel 集合

标签 php arrays laravel laravel-5 collections

我在使用 Laravel Collection 类时遇到一些问题。

我正在尝试做的事情:

  • 我有一个多站点解决方案,其中一个站点有“促进者”。有时一位协调员会出现在多个网站上,而不仅仅是一个。
  • 我想在主页上列出所有协调员和他们所在的网站,但我不想要多个用户。

所以我目前做的是:

  • 找到协调员。
  • 使用 Collection 收集协助者并使用 unique('name')

这为我提供了独特的辅助器,但只选择它检测到的第一个辅助器,然后删除其他辅助器。

假设我有这个收藏:

Collection { 
  #items: array:3 [
    0 => array:2 [
      "name" => "John"
      "site" => "Example"
    ]
    1 => array:2 [
      "name" => "Martin"
      "site" => "Another"
    ]
    2 => array:2 [
      "name" => "John"
      "site" => "Another"
    ]
  ]
}

使用 unique() 我会得到:

Collection { 
  #items: array:3 [
    0 => array:2 [
      "name" => "John"
      "site" => "Example"
    ]
    1 => array:2 [
      "name" => "Martin"
      "site" => "Another"
    ]
  ]
}

这就是我想要得到的:

Collection { 
  #items: array:3 [
    0 => array:2 [
      "name" => "John"
      "site" => ["Example", "Another"]
    ]
    1 => array:2 [
      "name" => "Martin"
      "site" => "Another"
    ]
  ]
}

有谁知道我如何使用 Laravel 的集合类来实现这一点?

最佳答案

当遇到收藏问题时,请记住 reduce是您武器库中的强大工具。

基于我无法开始工作的 Sam 的回答,我认为将 reduce 与 groupBy 一起使用应该可行......

$sites = collect([
  ["name" => "John", "site" => "Example"],
  ["name" => "Martin", "site" => "Another"],
  ["name" => "John", "site" => "Another"],
]);

$sites->groupBy('name')->reduce(function ($result, $item) {
  $result[] = [
    'name' => $item->first()['name'], 
    'sites' => $item->pluck('site')->toArray()
  ];

  return $result;
}, collect([]))->toArray();

然后从控制台...

λ php artisan tinker                                                                             
Psy Shell v0.8.2 (PHP 7.0.10 ÔÇö cli) by Justin Hileman                                          
>>> $sites = collect([                                                                           
...   ["name" => "John", "site" => "Example"],                                                   
...   ["name" => "Martin", "site" => "Another"],                                                 
...   ["name" => "John", "site" => "Another"],                                                   
... ]);                                                                                          
=> Illuminate\Support\Collection {#698                                                           
     all: [                                                                                      
       [                                                                                         
         "name" => "John",                                                                       
         "site" => "Example",                                                                    
       ],                                                                                        
       [                                                                                         
         "name" => "Martin",                                                                     
         "site" => "Another",                                                                    
       ],                                                                                        
       [                                                                                         
         "name" => "John",                                                                       
         "site" => "Another",                                                                    
       ],                                                                                        
     ],                                                                                          
   }                                                                                             
>>> $sites->groupBy('name')->reduce(function ($result, $item) {                                  
...   $result[] = ['name' => $item->first()['name'], 'sites' => $item->pluck('site')->toArray()];
...                                                                                              
...   return $result;                                                                            
... }, collect([]))->toArray();                                                                  
=> [                                                                                             
     [                                                                                           
       "name" => "John",                                                                         
       "sites" => [                                                                              
         "Example",                                                                              
         "Another",                                                                              
       ],                                                                                        
     ],                                                                                          
     [                                                                                           
       "name" => "Martin",                                                                       
       "sites" => [                                                                              
         "Another",                                                                              
       ],                                                                                        
     ],                                                                                          
   ]                                                                                             

需要注意的一件事是,您在问题中指定,如果只有一个站点,则站点应返回单个字符串,如果有多个站点,则应返回一个数组。上述解决方案不提供此功能!我认为这是不一致的,您应该始终为 sites 键返回一个数组,即使它只有一个值也是如此,因为这会使以后阅读和操作变得更加困难。

但是,如果这很重要,您可以在使用 pluck 设置数组时检查是否有很多站点,如果没有,您可以将其设置为单个字符串,如下所示:

$sites->groupBy('name')->reduce(function ($result, $item) {
  $result[] = [
    'name' => $item->first()['name'],
    'sites' => $item->pluck('site')->count() > 1 ? $item->pluck('site') : $item->first()['site']
  ];

  return $result;
}, collect([]))->toArray();

这会产生...

[                        
  [                      
    "name" => "John",    
    "sites" => [         
      "Example",         
      "Another",         
    ],                   
  ],                     
  [                      
    "name" => "Martin",  
    "sites" => "Another",
  ],                     
]                        

关于php - 复杂的 Laravel 集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42804242/

相关文章:

Javascript - Array.repeat 限制?

php - Laravel 5.6 查询生成器总和

php - jQuery - 追加 ajax 结果

php - 使用 PHP 存储图像

PHP 和 SQL 将复选框保存为数组

php - 如何使用当前登录的用户预填 voyager BREAD 表格?

javascript - 如何使用 javascript/axios 访问服务器的错误响应

javascript - CakePHP如何生成其外部密码

javascript - 如何使用 Ajax 和 Jquery 删除 MySQL 记录?

Java:计算对数组进行排序需要多长时间