Laravel の Collection は reverse()
メソッドによって逆順に並び替えることができます。
しかし以下のようにキーが付与(*1)されてしまうので、思い通りの比較ができないことがあります。
$collection = collect(['a', 'b', 'c', 'd', 'e']);
$reversed = $collection->reverse();
/*
[
4 => 'e',
3 => 'd',
2 => 'c',
1 => 'b',
0 => 'a',
]
*/
$otherCollection = collect(['e', 'd', 'c', 'b', 'a']);
echo $otherCollection === $reversed;
// false
そうじゃないんだよ、欲しいのは ['e', 'd', 'c', 'b', 'a']
なんだよって時は
values()
メソッドでキーを削除(*2)しちゃいましょう。
$collection = collect(['a', 'b', 'c', 'd', 'e']);
$reversed = $collection->reverse()->values();
/*
['e', 'd', 'c', 'b', 'a']
*/
$otherCollection = collect(['e', 'd', 'c', 'b', 'a']);
echo $otherCollection === $reversed;
// true
*1 「付与」→正確には「保持」
*2 「削除」→正確には「リセット」
説明は次の項にて
なぜなのか?
前項で使った「付与される」という表現は正確ではなく、 Laravel のドキュメントにもある通りキーが保持された結果として、「新たにキーが付与された」ように見えているだけです。
コレクション
前提としてPHPでは、全ての配列は以下のようにキーを持っています。
$array = ['a', 'b', 'c', 'd', 'e'];
/*
[
0 => 'a',
1 => 'b',
2 => 'c',
3 => 'd',
4 => 'e',
]
*/
さて、 Collection の reverse()
では PHP の array_reverse()
を利用していますが、
第2引数に true
を指定しているのにご注目👀
public function reverse()
{
return new static(array_reverse($this->items, true));
}
array_reverse()
の第2引数はpreserve_keys
「キーを保持」するパラメーターです。
array_reverse
PHP の配列の世界で表現するとこんな感じ。
$array = ['a', 'b', 'c', 'd', 'e'];
$otherArray = ['e', 'd', 'c', 'b', 'a'];
/*
[
0 => 'e',
1 => 'd',
2 => 'c',
3 => 'b',
4 => 'a',
]
*/
$reversed = array_reverse($array, true);
/*
[
4 => 'e',
3 => 'd',
2 => 'c',
1 => 'b',
0 => 'a',
]
*/
echo $otherArray === $reversed;
// false
// キーが一致しないので別の配列
Laravel のvalues()
では、array_values()
を呼び出しています。
public function values()
{
return new static(array_values($this->items));
}
array_values()
は配列の値を取り出してキーを振り直すメソッドなので、以下のように欲しい配列を取得することができるんですね。
array_values
$array = ['a', 'b', 'c', 'd', 'e'];
$otherArray = ['e', 'd', 'c', 'b', 'a'];
$reversed = array_values(array_reverse($array, true));
/*
[
0 => 'e',
1 => 'd',
2 => 'c',
3 => 'b',
4 => 'a',
]
*/
echo $otherArray === $reversed;
// true
// 配列でやるなら単純にこれでもいい
$reversed2 = array_reverse($array, false);
/*
[
0 => 'e',
1 => 'd',
2 => 'c',
3 => 'b',
4 => 'a',
]
*/
echo $otherArray === $reversed2;
// true