タイトルの通りなのですが、Laravelでコレクションをfilterするとインデックスが歯抜けになります。

環境


Laravel5.5で確認してます。

コード


実際に見てみましょう。下記のようなコレクションを作って出力してみます。

1
2
3
4
5
6
7
8
$collection = collect([]);
$collection->push(collect(["category" => "A", "name" => "P1"]));
$collection->push(collect(["category" => "B", "name" => "P2"]));
$collection->push(collect(["category" => "A", "name" => "P3"]));
$collection->push(collect(["category" => "C", "name" => "P4"]));

\Log::debug($collection);
\Log::debug($collection->toArray());

すると、下記のようになります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
[2018-05-23 10:47:54] local.DEBUG: [
{"category":"A","name":"P1"},
{"category":"B","name":"P2"},
{"category":"A","name":"P3"},
{"category":"C","name":"P4"}
]
[2018-05-23 10:47:54] local.DEBUG: array (
0 =>
array (
'category' => 'A',
'name' => 'P1',
),
1 =>
array (
'category' => 'B',
'name' => 'P2',
),
2 =>
array (
'category' => 'A',
'name' => 'P3',
),
3 =>
array (
'category' => 'C',
'name' => 'P4',
),
)

filterしてみる


で、上記のコレクションをfileterで絞り込んでみましょう。

1
2
3
4
5
6
$filterd = $collection->filter(function ($v) {
return ($v["category"] === "A");
});

\Log::debug($filterd);
\Log::debug($filterd->toArray());

これを出力すると下記のようにインデックスが抜けてしまいます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[2018-05-23 10:49:17] local.DEBUG: {
"0":{"category":"A","name":"P1"},
"2":{"category":"A","name":"P3"}
}
[2018-05-23 10:49:17] local.DEBUG: array (
0 =>
array (
'category' => 'A',
'name' => 'P1',
),
2 =>
array (
'category' => 'A',
'name' => 'P3',
),
)

インデックスの抜けを埋める


抜けを埋めるにはvaluseメソッドを使います。

1
2
3
4
5
6
$filterd = $collection->filter(function ($v) {
return ($v["category"] === "A");
})->values(); //ここでvaluesを呼ぶ

\Log::debug($filterd);
\Log::debug($filterd->toArray());

valuesでインデックスが振りなおされて歯抜けが解消されます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[2018-05-23 10:50:37] local.DEBUG: [
{"category":"A","name":"P1"},
{"category":"A","name":"P3"}
]
[2018-05-23 10:50:37] local.DEBUG: array (
0 =>
array (
'category' => 'A',
'name' => 'P1',
),
1 =>
array (
'category' => 'A',
'name' => 'P3',
),
)