コネヒト開発者ブログ

コネヒト開発者ブログ

本当に使える!PHPerなら知っておきたい便利な配列関数79選!! ver.2015

こんにちは、出前館愛用者の金城です。怠惰に過ごしたい休日といえば、deliveryですよね!!

f:id:connehito:20151028143346j:plain

さて、秋も深まりつつある今日この頃ですが、この場を借りてPHPにおける連想配列について書いてみたいと思います。
私達コネヒト開発陣一同は、親しみと敬意を以って連想配列に日々接しております。
このブログをご覧にいらっしゃるみなさまも、きっと日々の生活の中で・・・職場で、家庭で、あるいは気の置けない旧友との心温まる交流の場面でも、連想配列に夢中で居る事と思います。

そんな彼らについて、php.netを覗いてみると、このような記述があります。

配列で使用する便利な関数がたくさんあります

あの「一体、何に使うんです・・?」といった関数も標準で多く用意されていることで名高いPHP語をして曰くところの、「たくさん」です。
どんなものかとワクワクしますよね。

そこで、今回は「どんな関数があるのだろう」を見ていきたいと思います!
単に50音順に並べても分かりにくいので、公式リファレンスをベースにして、(主観で)7つのグループに分けながら「たくさんの」関数を紹介してみたいと思います!
見たこともない、まして使ったことのない(あるいはこの先も使うことのない!)関数が、きっと1つはあるはず・・?


PHPと79の配列関数

たくさんってどのくらいよ、と思って数えてみたら79*1個だそうです。*2
一般的な高校なら2クラス分の標準関数たちよ。。。

関数名とその概略は、公式ドキュメントから引用したものをそのまま利用しています。
ただし、グループ分けと並び順は私自身が行いました。大体、意味的に近いかな・・?と思われるものが近接するように配置しています。

※ 冒頭でわざとらしく「連想配列」と連呼していたのですが、下記は特に注記のない限り「配列」と「連想配列」は同じものとして扱います。
そういうもんですよね。PHPだし。

集合・共通・差分操作・合成系

(複数の)配列を比較して、新しく別の配列を作るといった目的の関数です。
似たようなものがあり数が多いのですが、基本的なdiff/intersect/mergeができれば、それ以上のものは要らないかな・・?という感も少々。
ただ、例えばarray_udiff/array_uintersectなどは$Obj->getValue()しての比較などといった用途も考えられますし、php.netのサンプルを見ると実際にそのようなケースが紹介されていたりします。無理して使うことはないが、知っているとチョット便利(でコードが簡潔になる)かな、と思いました。

一覧

(1つの配列を対象に操作するもの)

  • array_unique — 配列から重複した値を削除する

(要素の共通・差分を計算するもの)

  • array_diff — 配列の差を計算する
  • array_diff_assoc — 追加された添字の確認を含めて配列の差を計算する
  • array_diff_key — キーを基準にして配列の差を計算する
  • array_intersect_assoc — 追加された添字の確認も含めて配列の共通項を確認する
  • array_intersect_key — キーを基準にして配列の共通項を計算する
  • array_intersect_uassoc — 追加された添字の確認も含め、コールバック関数を用いて 配列の共通項を確認する
  • array_intersect_ukey — キーを基準にし、コールバック関数を用いて 配列の共通項を計算する
  • array_intersect — 配列の共通項を計算する

(合成するもの)

  • array_merge_recursive — 二つ以上の配列を再帰的にマージする
  • array_merge — ひとつまたは複数の配列をマージする

(コールバック関数を用いるもの)

  • array_diff_uassoc — ユーザーが指定したコールバック関数を利用し、 追加された添字の確認を含めて配列の差を計算する
  • array_diff_ukey — キーを基準にし、コールバック関数を用いて配列の差を計算する
  • array_udiff_assoc — データの比較にコールバック関数を用い、 追加された添字の確認を含めて配列の差を計算する
  • array_udiff_uassoc — データと添字の比較にコールバック関数を用い、 追加された添字の確認を含めて配列の差を計算する
  • array_udiff — データの比較にコールバック関数を用い、配列の差を計算する
  • array_uintersect_assoc — データの比較にコールバック関数を用い、 追加された添字の確認も含めて配列の共通項を計算する
  • array_uintersect_uassoc — データと添字の比較に個別のコールバック関数を用い、 追加された添字の確認も含めて配列の共通項を計算する
  • array_uintersect — データの比較にコールバック関数を用い、配列の共通項を計算する

再帰処理、フィルター系

配列に含まれる各要素に対して操作を行い、(新しい)配列を生成する関数です。あるいは、既存の配列に操作を行い変更をするもの。
個人的には、array_filterの第三3数として「keyだけを渡す」「keyとvalueを渡す」事ができると知った時は、ちょっと便利だなと思いました。
あと紛らわしいarray_walkarray_mapの引数の順番ですが、「副作用のあるwalkは、配列を1つだけ引数にとるので、最初がinput」「副作用がなく、可変長なinputをとるmapはcallbackが最初」と記憶しています。

一覧

  • array_filter — コールバック関数を使用して、配列の要素をフィルタリングする
  • array_map — 指定した配列の要素にコールバック関数を適用する
  • array_reduce — コールバック関数を用いて配列を普通の値に変更することにより、配列を再帰的に減らす
  • array_product — 配列の値の積を計算する
  • array_walk — 配列の全ての要素にユーザー定義の関数を適用する
  • array_walk_recursive — 配列の全ての要素に、ユーザー関数を再帰的に適用する
  • array_sum — 配列の中の値の合計を計算する
  • array_change_key_case — 配列のすべてのキーの大文字小文字を変更する

ソート系

配列に含まれる要素を、並び替える関数です。ここだけarray_*という名前の関数が少ないですね。
あまり出会ったことがないけど使う機会多そうだよな・・・?と思っているのは、natsortでしょうか。natural-sort。名の通りですが、これは公式にある例示が分かりやすいので、もし良かったらそちらで概要を掴んでください。
割とどれも利用シーン多いかな?とは思いつつ、無理にuksortなどに処理を突っ込もうとすると「普通に別の配列作っていった方が楽だったよね」となる事も多いように思います。

一覧

(副作用のあるもの)

  • array_multisort — 複数の多次元の配列をソートする
  • arsort — 連想キーと要素との関係を維持しつつ配列を逆順にソートする
  • asort — 連想キーと要素との関係を維持しつつ配列をソートする
  • krsort — 配列をキーで逆順にソートする
  • ksort — 配列をキーでソートする
  • natcasesort — 大文字小文字を区別しない"自然順"アルゴリズムを用いて配列をソートする
  • natsort — "自然順"アルゴリズムで配列をソートする
  • rsort — 配列を逆順にソートする
  • sort — 配列をソートする
  • uasort — ユーザー定義の比較関数で配列をソートし、連想インデックスを保持する
  • uksort — ユーザー定義の比較関数を用いて、キーで配列をソートする
  • usort — ユーザー定義の比較関数を使用して、配列を値でソートする
  • shuffle — 配列をシャッフルする

(副作用のないもの)

  • array_reverse — 要素を逆順にした配列を返す

作成・変更系

新規に別の配列(もしくは複数の変数)を作成する目的を持つ関数です。
array_count_valuesには、出会って依頼しばしばお世話になっています!(出現数を基にランキングを作ったり〜などと使います)
その他にも、array_fliparray_combineといったパワフルな処理を簡単にするものも多いです。
あとarray_fill_keys(range(0, 5), $ar)みたいな感じで、指定長の初期化済みデータの生成なんかをするのが好きです。
array_columnに関しては、5.5からの導入という事で、馴染みの薄い方も多いと思いますが素敵ですよね…!

一覧

(新規に配列を作るもの)

  • array — 配列を生成する
  • range — ある範囲の整数を有する配列を作成する
  • array_pad — 指定長、指定した値で配列を埋める
  • array_fill_keys — キーを指定して、配列を値で埋める
  • array_fill — 配列を指定した値で埋める

(既存の配列から集計や抽出を行うもの)

  • array_chunk — 配列を分割する
  • array_combine — 一方の配列をキーとして、もう一方の配列を値として、ひとつの配列を生成する
  • array_count_values — 配列の値の数を数える
  • array_flip — 配列のキーと値を反転する
  • array_column — 入力配列から単一のカラムの値を返す
  • array_keys — 配列のキーすべて、あるいはその一部を返す
  • array_values — 配列の全ての値を返す

(配列から単一要素を取り出すもの・加えるもの)

  • array_pop — 配列の末尾から要素を取り除く
  • array_push — 一つ以上の要素を配列の最後に追加する
  • array_rand — 配列から一つ以上の要素をランダムに取得する
  • array_shift — 配列の先頭から要素を一つ取り出す
  • array_unshift — 一つ以上の要素を配列の最初に加える

(配列から一部を取り出すもの・変更するもの)

  • array_slice — 配列の一部を展開する
  • array_splice — 配列の一部を削除し、他の要素で置換する
  • array_replace — 渡された配列の要素を置き換える
  • array_replace_recursive — 渡された配列の要素を再帰的に置き換える

要素・配列のチェック系

配列に含まれる要素の値もしくはキーに関して検査するもの、あるいは配列自体の状態を調べるものです。
array_key_existsなどは、キーの有無を通常通りに検査するのであればisset($ar[$key])などで代用可能だしその方が一般的な気がしますが、引数として扱えるという点で利用可能なケースが異なりそうですね。

一覧

(要素の検査をする)

  • array_key_exists — 指定したキーまたは添字が配列にあるかどうかを調べる
  • key_exists — array_key_exists のエイリアス
  • in_array — 配列に値があるかチェックする
  • array_search — 指定した値を配列で検索し、見つかった場合に対応するキーを返す

(配列自体の状態を調べる)

  • count — 変数に含まれるすべての要素、 あるいはオブジェクトに含まれる何かの数を数える
  • sizeof — count のエイリアス

イテレータ・ポインタ操作系

ポインタをいじったりするものです。
個人的にはこの辺りに少々ハマりそうな点を孕んでいるように思っていて、 例えばcurrenntの項には配列中に boolean FALSE の要素が含まれていると、 それを配列の終わりと区別することができません。などと書かれております。あ、そうか、なるほどなぁと思う次第です。
他方で、取り出したばかりのデータから、最初の要素を利用したいといった場合には$val = $ar[0];などとするところを$val = current($ar)といった風に書き換えることもできるのかなと思います。array_filterを書けた後なども、これで安心ですね。

一覧

  • current — 配列内の現在の要素を返す
  • each — 配列から現在のキーと値のペアを返して、カーソルを進める
  • end — 配列の内部ポインタを最終要素にセットする
  • key — 配列からキーを取り出す
  • next — 内部配列ポインタを進める
  • pos — current のエイリアス
  • prev — 内部の配列ポインタをひとつ前に戻す
  • reset — 配列の内部ポインタを先頭の要素にセットする

変数⇄配列を変換するもの

少々特殊ですが、「配列に含まれる要素をそのまま変数としたい(もしくはその逆)」といった目的のものです。 MVCを利用していたり、何らかのテンプレートエンジンを利用する際には割と見かけるでしょうか。例えば、viewに渡したい変数の宣言や設定を、compactを上手く利用することで1箇所にまとめる(コンパクトですね!)という様なユースケースがあると思います。 また、extraは第2,3引数に指定可能な内容を知識として備えておくことによって、より良い付き合い方ができるのかなと感じます。

  • compact — 変数名とその値から配列を作成する
  • extract — 配列からシンボルテーブルに変数をインポートする
  • list — 配列と同様の形式で、複数の変数への代入を行う

このエントリーを書いてみての感想

多い・・・まぁ雑学ネタくらいにはなるのではないでしょうか。「ねぇ、PHPの配列に関する関数って何個あるか知ってるかい?」「えー、わかんなーい」「79個さ!」みたいな。 あとはよろしくお願いします。
気になるものがあったら、ぜひhttp://php.net/{$関数名}でドープなPHPワールドにダイブしてみてください!

最後に、UNIX哲学にも挙げられている「1つのことをシンプルにやれ」というKISS原則のリンクを貼り付けて、本稿を閉じたいと思います。 https://ja.wikipedia.org/wiki/KISS%E3%81%AE%E5%8E%9F%E5%89%87

弊社CTOが配列についてお話します!!

現在、コネヒト株式会社では色んなエンジニアを募集しています!!
かくいう私は、初対面の場で(面接というよりもカジュアルな面談でした(ノ∀'*)) 「CakePHP使っていると、Hashクラスが可愛くて可愛くて・・・」「うわ〜、分かる〜〜!」などといった交流をしたものです。
少しでも「ベンチャー」「コミュニティ」「PHP」「Undefined offset」なんてキーワードにピクっと来た方は、ぜひ遊びに来てください!

先週から自転車通勤に挑戦している金城でした。

*1:https://ja.wikipedia.org/wiki/79

*2:このエントリーがクソ煽りタイトルに変更されたのは、言わずもがなこのタイミングです