【问题标题】:How to iterate through two collections of the same length using foreach如何使用foreach遍历两个相同长度的集合
【发布时间】:2017-05-02 05:59:16
【问题描述】:

如果我们想连接两个集合的某些属性,假设它们具有相同的长度,例如:

集合 1:

$collection1 = Collection { ▼
  #items: array:2 [ ▼
    0 => Item { ▼
      +id: 1
      +first_name: 'first_name 1'
      +last_name: 'first_name 1'
      +nbr_hours: 9
    }
    1 => Item { ▼
      +id: 2
      +first_name: 'first_name 2'
      +last_name: 'first_name 2'
      +nbr_hours: 10
    }
  ]
}

系列 2:

$collection2 = Collection { ▼
  #items: array:2 [ ▼
    0 => Item { ▼
      +id: 1
      +first_name: 'first_name 1'
      +last_name: 'first_name 1'
      +nbr_hours: 10
    }
    1 => Item { ▼
      +id: 2
      +first_name: 'first_name 2'
      +last_name: 'first_name 2'
      +nbr_hours: 12
    }
  ]
}

我们如何同时循环遍历它们并连接 nbr_hours 属性,例如,输出将如下所示:

$nested_collection = Collection { ▼
  #items: array:2 [ ▼
    0 => Item { ▼
      +id: 1
      +first_name: 'first_name 1'
      +last_name: 'first_name 1'
      +nbr_hours: 19
    }
    1 => Item { ▼
      +id: 2
      +first_name: 'first_name 2'
      +last_name: 'first_name 2'
      +nbr_hours: 22
    }
  ]
}

【问题讨论】:

标签: php laravel collections laravel-5 foreach


【解决方案1】:

首先,要求

需要使用 foreach 循环遍历集合的解决方案

使用两个具有相同项目且顺序相同的集合的方法

您可以使用您遍历的每个元素的索引从另一个集合中获取“伙伴元素”,以防每个集合的项目计数和排序相同。

foreach($collection1 as $index => $item){
    $hours = $item->nbr_hours . $collection2[$index]->nbr_hours;
}

不考虑排序和项目计数的方法

当您的集合元素顺序不同,或者集合项计数不同时,查询看起来会更复杂一些。在这种情况下,您需要查询 id 相同的元素。为此,我们可以将集合索引更改为包含模型的 id。现在我们可以再次使用一个元素的索引在另一个集合中找到对应的元素。

$collection2 = $collection2->keyBy('id'); //Change indexes to model ids 
$collection1 = $collection1->keyBy('id'); //For both collections
foreach($collection1 as $index => $item){
    $hours = $item->nbr_hours . $collection2->get($index)->nbr_hours;
}

【讨论】:

  • 如果值的顺序不同怎么办。
  • 然后可能会创建一个更复杂的查询@SougataBose
【解决方案2】:

这是一个带有数组的示例,您可以做些什么来实现这一点 -

$c1 = [
['id' => 1, 'hrs' => 9],
['id' => 2, 'hrs' => 12],
];

$c2 = [
['id' => 1, 'hrs' => 10],
['id' => 2, 'hrs' => 11],
];

foreach($c1 as &$c) {
    // get the index for the id from the 2nd array
    $c2_index = array_search($c['id'], array_column($c2, 'id'));
    // Increment the value
    $c['hrs'] += $c2[$c2_index]['hrs'];
}

Demo

【讨论】:

    【解决方案3】:

    如果你想使用 Collection 方法,你可以使用这种方法:

        $zip = $c1->zip($c2->toArray());
        $m = $zip->map(function($items, $key) {
            $sum = 0;
            foreach ($items as $k => $item) {
                $sum += $item['nbr_hours'];
            }
            $r = $items[$k];
            $r['nbr_hours'] = $sum;
            return $r;
        });
    

    基本上,zip 方法会将数组“合并”在同一个键中。然后,如果您使用map 方法,您可以遍历主键。之后,您可以将两个数组都作为项目处理。因此,您可以进行任何需要的操作,然后返回一个新数组作为结果。

    【讨论】:

      【解决方案4】:

      您可以将map 方法用作:

      $nested_collection  = $collection1->map(function ($item, $key) use($collection2) {
          $item->nbr_hours = $item->nbr_hours + $collection2->get($key)->nbr_hours;
          return $item;
      });
      

      注意 - 如果值的顺序不同,则可以使用values 方法。

      values 方法返回一个新集合,其中键重置为连续整数

      【讨论】:

        【解决方案5】:

        对@AmitGupta 的回答稍作修改。如果集合2需要$item->id匹配。试试下面的答案。 :)

        $nested_collection = $collection1->map(function($item) use ($collection2) {
            $item->nbr_hours += $collection2->where('id', $item->id)->first()->nbr_hours;
        
            return $item;
        });
        

        让我知道:)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-04-23
          • 2018-12-10
          • 2016-02-23
          • 1970-01-01
          • 2016-11-16
          • 2011-03-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多