配列の最後を求めるRFC


PHPは配列関数がめったらやたら充実しているのですが、何故か配列の最初や最後の要素を取得する関数がありません。

    $array = ['a'=>1, 'b'=>2, 'c'=>3];

    // 配列の最初のキーと値
    reset($array); // 1
    key($array); // 'a'

    // 配列の最後のキーと値
    end($array); // 3
    key($array); // 'c'

何故かわざわざ配列の内部ポインタを操作しなければなりません。
もしくはarray_sliceで切り出すなどの面倒な手順が必要です。

ということでどうにかしようというRFCが2018/06/11に提出されました。
以下はPHP RFC: array_key_first(), array_key_last() and array_value_first(), array_value_last()の日本語訳です。

PHP RFC: array_key_first(), array_key_last() and array_value_first(), array_value_last()

Introduction

配列はパワフルなデータ構造ですが、ときに副作用なしに配列の最初や最後のキー、値を取り出せると便利なことがよくあります。
このタスクを解決するために、このRFCでは4つの関数をコアに追加します。

    $key = array_key_first($array);
    $key = array_key_last($array);
    $value = array_value_first($array);
    $value = array_value_last($array);

Proposal

現在のPHPでは、配列の最初や最後のキー・値を取り出したいときには、関数reset()end()、およびkey()を使って配列の内部ポインタを変更する必要があります。
他の実装としてはarray_keys($array)[0]やループで回す方法などがありますが、前者は$arrayが空の場合にエラーが発生することがあったり、後者は複雑性が上がってわかりにくくなります。

配列からデータを取得するためだけに内部ポインタを変更しないで済むように、また平易な書き方ができるように、このRFCでは配列キーを扱うための2関数と、配列値を扱うための2関数を追加します。

配列の最初の要素のキーを取得するためにarray_key_firstが、配列の最後の要素のキーを取得するためにarray_key_lastが追加されます。

    // 連想配列
    $array = ['a' => 1, 'b' => 2, 'c' => 3];

    $firstKey = array_key_first($array); // 'a'
    $lastKey = array_key_last($array);   // 'c'

    // 普通の配列
    $array = [1 => 'a', 2 => 'b', 3 => 'c'];

    $firstKey = array_key_first($array); // 1
    $lastKey = array_key_last($array);   // 3

    // 空の配列
    $array = [];

    $firstKey = array_key_first($array); // null
    $lastKey = array_key_last($array);   // null

配列の最初の要素の値を取得するためにarray_value_firstが、配列の最後の要素の値を取得するためにarray_value_lastが追加されます。

    // 連想配列
    $array = ['a' => 1, 'b' => 2, 'c' => 3];

    $firstKey = array_value_first($array); // 1
    $lastKey = array_value_last($array);   // 3

    // 普通の配列
    $array = [1 => 'a', 2 => 'b', 3 => 'c'];

    $firstKey = array_value_first($array); // 'a'
    $lastKey = array_value_last($array);   // 'c'

    // 空の配列
    $array = [];

    $firstKey = array_value_first($array); // null
    $lastKey = array_value_last($array);   // null

4関数は全て、要求されたキーか値を返します。
空の配列に対してはnullを返します。
配列以外の引数にはE_WARNINGを発してnullを返します。

Backward Incompatible Changes

後方互換性の破壊はなし。

Proposed PHP Version(s)

PHP7.xの次のどこかで。

RFC Impact

このRFCは4つの新しい関数を追加するため、ユーザランドで同じ名前のヘルパ関数を作っていた場合に影響を与える可能性があります。
実装された関数は意味のある名前なので、カスタム関数は交換可能な同じ機能を実装する必要があります。

SAPIsやopcacheには何の影響もありません。

Proposed Voting Choices

このRFCはPHPの構文を変更しないので、50%+1の賛成で可決されます。

Patches and Tests

機能とテストを提供するプルリクエストはGitHubにあります。

感想

他のRFCを見てたら、2年前に提出されたPHP RFC: array_key_(first|last|index)というのとほぼ同じでした。
というより、このRFCが止まってるから勝手に実装しちゃったぜみたいなノリでした。

ループの最後だけ、みたいな処理はありがちなので、この関数が実装されるとありがたいですね。

ところで、どうしてarray_first()/array_last()がないのか。