44
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PHPで配列の最後の値を取得する

Last updated at Posted at 2018-09-21

いろいろな言語で配列の最後の要素でPHPがハブられてました。
ということでここでやりましょう。

最後の要素をとる関数 end に副作用があるらしい。

see PHP – 配列の最後の要素の判定にend()は使わない方がいい話
see PHPで配列の最後の値を取得する

end を使うべきかどうかはケースバイケース。PHP 難しい。

配列にendを使って問題になるのはよほど特殊なケースだけなので、通常はendを使ってしまって問題ありません。

	$array = [1, 2, 3];
	$value = end($array); // 3

副作用としては$arrayの配列ポインタが配列の最後になるので、その後リセットせずにcurrentnextあたりを使うと想定外の値が返ってくる場合があります。

しかしresetend以外の配列ポインタ操作関数を使うのは変態だけなので、一般人には影響しません。
あらゆる配列操作はforeachを使うべきで、そしてforeachは配列ポインタとは関係なく全件ループする1ので、配列ポインタの現在地などは意識しなくていいです。

実用的な問題としては、endは参照なので値しか渡せません。
つまりend(getArray());のようなことができません
ということでPHP7.3.0でarray_key_last実装されました

	// 配列ポインタを変えずに最後の値を取得
	$array = [1, 2, 3];
	$value = $array[array_key_last($array)]; // 3
	
	// 関数も渡せる
	function getArray(){ return [1, 2, 3]; }
	$value = getArray()[array_key_last(getArray())]; // 3

なぜかarray_value_last却下されてしまったので、$value = array_value_last($array)とは書けません。残念ですね。

ちなみに、冒頭の記事で紹介されている配列の最後の要素の判定にend()は使わない方がいい話は単に使い方が間違ってるだけですね。
値を比較してるから同じ値がイコールになっているだけで、end云々は全く関係ありません。
正しい判定にはキーを使います

$array = [
    0 => "aaa", 
    1 => "bbb", 
    2 => "ccc", 
    3 => "bbb", 
    4 => "ddd", 
    5 => "ccc"];

// 7.3.0以降は$key = array_key_last($array);
end($array);
$key = key($array);

foreach($array as $k=>$v){
    if($k !== $key){
        print "${k}=>${v} まだ最後じゃないよ\n";
    }else{
        print "${k}=>${v} これが最後だよ\n";
    }
}

7.3.0未満は$keyの求め方が残念な感じ。

  1. 正確には『PHP7では全く無関係』『PHP5では配列ポインタをリセットする』。いずれにせよ配列ポインタの現在地にかかわらず全件ループする。

44
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
44
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?