Php 复杂拉维集合

Php 复杂拉维集合,php,arrays,laravel,laravel-5,collections,Php,Arrays,Laravel,Laravel 5,Collections,我在拉威尔收集课上遇到了一些问题 我想做什么: Collection { #items: array:3 [ 0 => array:2 [ "name" => "John" "site" => "Example" ] 1 => array:2 [ "name" => "Martin" "site" => "Another" ] 2 => array:2 [

我在拉威尔收集课上遇到了一些问题

我想做什么:

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"
    ]
  ]
}
  • 我有一个多站点解决方案,其中一个站点有“促进者”。有时,一个主持人出现在多个站点上,而不仅仅是一个站点
  • 我想列出所有的主持人和他们在主页上的网站,但我不想有多个用户
所以我现在做的是:

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('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"
    ]
  ]
}
这就是我想要得到的:


有人知道我如何使用Laravel的collection类来实现这一点吗?

假设$collection是主要的集合,您可以通过链接来实现这一点

 $collection->groupBy('name')->map(function($facilitators) {
     return ['name' => $facilitators->first()['name'], 'site' => $facilitators->pluck('site')->toArray()];
})->values()->toArray();

首先,我们按名称分组,这样它将在集合中给出二维数组,然后迭代到该数组,名称将是公共的,所以从第一个元素获取它,然后从所有元素提取站点将其转换为数组,使用flatMap将使其单级嵌套

当你沉迷于收藏时,请记住,它是你武器库中一个强大的工具

基于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键返回一个数组,即使它只有一个值,因为这将使以后的读取和操作更加困难

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

$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",
  ],                     
]                        

为什么不使用
Group\u concat
?这可能会解决您的问题。站点未分配给数据库级别的用户。我将遍历所有站点,找到它们的主持人,然后将站点名称添加到主持人对象中。我真的要用这些收藏品来做这件事。基本上,我想做的是:获取唯一但合并一个键。尝试使用
GroupBy
。这是一个例子。这可能对你有帮助。你运行过这个代码吗?这对我不起作用
$facilitators->first()->name
将返回一个错误,它无法访问name,因为我认为
first()
方法返回一个数组,而您试图像对象一样访问它。集合中的任何方法都不会返回数组,除了toArray()和all()first返回集合中的第一个项,我认为该项是object,如果该项本身是array,则需要进行一些修改,但所示的转储似乎具有嵌套的collectionPerfect!这正是我想要做的。我将深入探讨reduce方法,它似乎是一种非常强大的方法。谢谢你!是的,您实际上可以使用reduce重新实现任何收集方法。如果您想更深入地使用集合,我强烈推荐此资源:-快乐编码@哈基姆回答得很好。你的回答真的很有价值。坚持下去。上帝保佑你,谢谢你,曼尼什!上帝也保佑你。这要归功于Sam,当我开始从他的答案开始工作时,他发布了第一个答案,因为我最初的解决方案是只使用reduce,这变得有点复杂。