はい‐れつ【配列/排列】
配列 連想配列
配列
配列関数(array)
導入
これらの関数により様々な手法で配列にアクセスし、操作することが可能 になります。配列は、変数の組を保存、管理、操作する基本的な要素です。通常の配列および多次元配列がサポートされており、ユーザが定義したり、 他の関数で作成することも可能です。いくつかのデータベース処理関数は、 データベースのクエリから配列を返しますし、いくつかの関数は配列を返 します。
PHPでの配列の実装や使用方法の詳細については、マニュアルの 配列に関する節を参照下 さい。 その他の配列の操作方法については、 配列演算子も 参照ください。
要件
外部ライブラリを必要としません。インストール手順
PHP コアに含まれるため、 追加のインストール無しで使用できます。実行時設定
設定ディレクティブは定義されていません。リソース型
リソース型は定義されていません。定義済み定数
以下の定数は、PHP コアに含まれており、常に利用可能です。- CASE_LOWER (integer)
- CASE_LOWERは、 array_change_key_case()で使用され、 配列のキーを小文字に変換するために使用されます。小文字は、 array_change_key_case()のデフォルトのケースで もあります。
- CASE_UPPER (integer)
- CASE_UPPERは、 array_change_key_case()で使用され、配列のキー を大文字に変換するために使用されます。
ソース順のフラグ:
- SORT_ASC (integer)
- SORT_ASCは、 array_multisort()でソート順を昇順にするために 使用されます。
- SORT_DESC (integer) (integer)
- SORT_DESCは、 array_multisort()でソート順を降順にするために 使用されます。
ソート型のフラグ: 種々のソート関数で使用されます
- SORT_REGULAR (integer)
- SORT_REGULARは通常の比較するために使用され ます。
- SORT_NUMERIC (integer)
- SORT_NUMERICは数値で比較を行うために使用さ れます。
- SORT_STRING (integer)
- SORT_STRINGは文字列として比較を行うために使 用されます。
- SORT_LOCALE_STRING (integer)
- SORT_LOCALE_STRINGは現在のロケールに基づいた 文字列として比較を行うために使用されます。 PHP 4.4.0と5.0.2で追加 されました。
- COUNT_NORMAL (integer)
- COUNT_RECURSIVE (integer)
- EXTR_OVERWRITE (integer)
- EXTR_SKIP (integer)
- EXTR_PREFIX_SAME (integer)
- EXTR_PREFIX_ALL (integer)
- EXTR_PREFIX_INVALID (integer)
- EXTR_PREFIX_IF_EXISTS (integer)
- EXTR_IF_EXISTS (integer)
- EXTR_REFS (integer)
参考
is_array(), explode(), implode(), split(), preg_split(), および join() も参照してください。目次
- array_change_key_case — 配列のキーを全て小文字または大文字にして返す
- array_chunk — 配列を分割する
- array_combine — 一方の配列をキーとして、もう一方の配列を値として、ひとつの配列を生成する
- array_count_values — 配列の値の数を数える
- array_diff_assoc — 追加された添字の確認を含めて配列の差を計算する
- array_diff_key — キーを基準にして配列の差を計算する
- array_diff_uassoc — ユーザが指定したコールバック関数を利用し、 追加された添字の確認を含めて配列の差を計算する
- array_diff_ukey — キーを基準にし、コールバック関数を用いて配列の差を計算する
- array_diff — 配列の差を計算する
- array_fill_keys — キーを指定して、配列を値で埋める
- array_fill — 配列を指定した値で埋める
- array_filter — コールバック関数を使用する配列要素フィルタ
- array_flip — 配列のキーと値を反転する
- array_intersect_assoc — 追加された添字の確認も含めて配列の共通項を確認する
- array_intersect_key — キーを基準にして配列の共通項を計算する
- array_intersect_uassoc — 追加された添字の確認も含め、コールバック関数を用いて 配列の共通項を確認する
- array_intersect_ukey — キーを基準にし、コールバック関数を用いて 配列の共通項を計算する
- array_intersect — 配列の共通項を計算する
- array_key_exists — 指定したキーまたは添字が配列にあるかどうかを調べる
- array_keys — 配列のキーをすべて返す
- array_map — 指定した配列の要素にコールバック関数を適用する
- array_merge_recursive — 二つ以上の配列を再帰的にマージする
- array_merge — ひとつまたは複数の配列をマージする
- array_multisort — 複数の多次元の配列をソートする
- array_pad — 指定長、指定した値で配列を埋める
- array_pop — 配列の末尾から要素を取り除く
- array_product — 配列の値の積を計算する
- array_push — 一つ以上の要素を配列の最後に追加する
- array_rand — 配列から一つ以上の要素をランダムに取得する
- array_reduce — コールバック関数を用いて配列を普通の値に変更することにより、 配列を再帰的に減らす
- array_reverse — 要素を逆順にした配列を返す
- array_search — 指定した値を配列で検索し、見つかった場合に対応するキーを返す
- array_shift — 配列の先頭から要素を一つ取り出す
- array_slice — 配列の一部を展開する
- array_splice — 配列の一部を削除し、他の要素で置換する
- array_sum — 配列の中の値の合計を計算する
- array_udiff_assoc — データの比較にコールバック関数を用い、 追加された添字の確認を含めて配列の差を計算する
- array_udiff_uassoc — データと添字の比較にコールバック関数を用い、 追加された添字の確認を含めて配列の差を計算する
- array_udiff — データの比較にコールバック関数を用い、配列の差を計算する
- array_uintersect_assoc — データの比較にコールバック関数を用い、 追加された添字の確認も含めて配列の共通項を計算する
- array_uintersect_uassoc — データと添字の比較にコールバック関数を用い、 追加された添字の確認も含めて配列の共通項を計算する
- array_uintersect — データの比較にコールバック関数を用い、配列の共通項を計算する
- array_unique — 配列から重複した値を削除する
- array_unshift — 一つ以上の要素を配列の最初に加える
- array_values — 配列の全ての値を返す
- array_walk_recursive — 配列の全ての要素に、ユーザー関数を再帰的に適用する
- array_walk — 配列の全ての要素にユーザ関数を適用する
- array — 配列を生成する
- arsort — 連想キーと要素との関係を維持しつつ配列を逆順にソートする
- asort — 連想キーと要素との関係を維持しつつ配列をソートする
- compact — 変数名とその値から配列を作成する
- count — 変数に含まれる要素、 あるいはオブジェクトに含まれるプロパティの数を数える
- current — 配列内の現在の要素を返す
- each — 配列から、次のキーと値のペアを返す
- end — 配列の内部ポインタを最終要素にセットする
- extract — 配列からシンボルテーブルに変数をインポートする
- in_array — 配列に値があるかチェックする
- key — 連想配列からキーを取り出す
- krsort — 配列をキーで逆順にソートする
- ksort — 配列をキーでソートする
- list — 配列と同様の形式で、複数の変数への代入を行う
- natcasesort — 大文字小文字を区別しない"自然順"アルゴリズムを用いて配列をソートする
- natsort — "自然順"アルゴリズムで配列をソートする
- next — 内部配列ポインタを進める
- pos — current() のエイリアス
- prev — 内部の配列ポインタをひとつ前に戻す
- range — ある範囲の整数を有する配列を作成する
- reset — 配列の内部ポインタを先頭の要素にセットする
- rsort — 配列を逆順にソートする
- shuffle — 配列をシャッフルする
- sizeof — count() のエイリアス
- sort — 配列をソートする
- uasort — ユーザー定義の比較関数で配列をソートし、連想インデックスを保持する
- uksort — ユーザー定義の比較関数を用いて、キーで配列をソートする
- usort — ユーザー定義の比較関数を使用して、配列を値でソートする
配列
配列
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2024/04/12 06:05 UTC 版)
この記事は検証可能な参考文献や出典が全く示されていないか、不十分です。(2017年9月) |
この記事は中立的な観点に基づく疑問が提出されているか、議論中です。(2018年11月) |
この記事では、コンピュータ・プログラムにおいて配列(はいれつ、英: array)と呼ばれているデータ構造およびデータ型について説明する。計算科学方面ではベクトルという場合もある。また、リストも参照。一般に、添え字で個々の要素を区別する。
配列とは
複数の要素(値)の集合を格納・管理するのに用いられるデータ構造が配列である。数学のベクトルおよび行列に近い概念であり、実際にベクトルおよび行列をプログラム上で表現する場合に配列が使われることが多い。同様に複数要素の集合を管理するデータ構造(コレクションあるいはコンテナ)には連結リストやハッシュテーブルなどがあるが、通常はメモリアドレス上での連続性の違いなどから配列とは区別される。1次元の配列は特に線形配列 (linear array) とも呼ばれる。
例えば、6人の生徒の平均点を計算するプログラムを書くとする。配列を使わない方法では、それぞれの生徒に対応する変数を、次のように個別に用意することだろう。
int score1;
int score2;
int score3;
int score4;
int score5;
int score6;
// 例えば標準入力経由で各生徒の得点を各変数に読み込んだとする。
double mean = (double)(score1 + score2 + score3 + score4 + score5 + score6) / 6;
しかし、この方法では生徒数が増減したときに、変更や拡張が大変になってしまう。より良い解は6要素の配列を使うことである。
int score[6]; // 6要素の配列が作られる。
// 例えば標準入力経由で各生徒の得点を配列scoreに読み込んだとする。
double mean = 0;
for (int i = 0; i < 6; ++i) {
mean += score[i]; // 配列の各要素へは、変数scoreを通してscore[0]からscore[5]のようにしてアクセスする。
}
mean /= 6;
配列を用いることで、添え字演算子による統一的なアクセスおよび一括処理が可能となる。また、処理すべきデータ個数が増減したときにも対応しやすくなる。
配列の動的確保
前述の例では、プログラム中で宣言時に指定した固定のサイズ(整数定数)による配列確保(静的確保)であった。実用的には、配列の要素数が宣言時(あるいはコンパイル時)に静的に決まってしまうよりも、実行時に要素数を動的に指定して配列を確保できたほうが便利なことがある。例えば、縦横任意サイズの画像ファイルから全画素情報を読み出す場合や、コンピュータで利用可能な空きメモリ量に合わせて扱うデータ個数上限を変化させたい場合などである。
多くのプログラミング言語では、配列のサイズをプログラム実行時に指定して配列を生成する(動的に確保する)手段が用意されている。例えばC言語ではmalloc関数やcalloc関数を利用する。確保に成功するとメモリブロック(配列先頭要素)へのポインタが返却され、このポインタ経由で配列を操作する。
int numStudents;
// 例えば標準入力経由でnumStudentsに生徒数 (> 0) を読み込んだとする。
int* score = calloc(numStudents, sizeof(int)); // 要素数がnumStudents、各要素のサイズがint型のサイズであるような配列を動的に確保し、0で初期化する。
// 例えば標準入力経由で各生徒の得点を配列scoreに読み込んだとする。
double mean = 0;
for (int i = 0; i < numStudents; ++i) {
mean += score[i]; // 動的に確保した場合でも、配列の添え字シンタックスは同じ。
}
mean /= numStudents;
free(score); // 使い終わった配列のメモリ領域を解放する。
C++などの後発の言語では、動的メモリ確保のために通例new演算子が用意されていることが多く、配列の動的確保には型と要素数を指定するnew[]
演算子を使用する。
int numStudents;
// 例えば標準入力経由でnumStudentsに生徒数 (> 0) を読み込んだとする。
int* score = new int[numStudents](); // 要素数がnumStudentsであるようなint型の配列を動的に確保し、0で初期化する。
// 例えば標準入力経由で各生徒の得点を配列scoreに読み込んだとする。
double mean = 0;
for (int i = 0; i < numStudents; ++i) {
mean += score[i]; // 動的に確保した場合でも、配列の添え字シンタックスは同じ。
}
mean /= numStudents;
delete[] score; // 使い終わった配列のメモリ領域を解放する。
いずれにせよ、C/C++ではmallocあるいはnewによってヒープ領域から確保したメモリは明示的に解放する必要があり、解放を忘れるとメモリリークの原因となる。プログラミングの煩雑さを解消するため、C++ではコンストラクタ・デストラクタを使ったメモリ寿命管理手法 (RAII) が使われることが多い。Javaなどの後発の言語ではガベージコレクションによる自動解放を導入していることが多く、また配列の確保に関して静的確保・動的確保といった区別をしない(配列の確保はすべて動的確保である)ことが多い。
通例、上記のようにして「動的に確保された配列」は、後述の「動的配列」とは異なり、要素の追加時に自動的にサイズを増加させるようなことはできない。
なお、C言語には後述する可変長配列も言語機能として備わっているが、メモリの生存期間などの面で違いがある。
計算オーダー
「配列」という語は、抽象データ型というよりも、添え字をオフセットとしてメモリのアドレスにマップすることで、Ο(1) でアクセスできる具象あるいは実装を特に指す場合がある(その意味では、次節の連想配列などは「配列」ではない、ということになる)。
配列に要素を挿入/削除する際、要素間に「隙間」が無いようにするには、線形リストと異なり、挿入/削除位置から後ろの領域にあるすべてのデータの移動(コピー)が必要となる。そのため、挿入/削除にO(n)時間かかる。さらに配列は連続領域を必要とするため、挿入時に領域が不足した場合に拡張する際のメモリ再確保のコストが高い。
探索は一般的には線型探索になるためΟ(n)だが、データがソート済みであれば二分探索を使うことでΟ(log n)に軽減することもできる(抽象データ型としては、sorted array などの名前で別のデータ構造と考える場合もある。en:Sorted array を参照)。
さまざまな配列
連想配列
添え字は一般に通例0か1始まりの (非負) 整数である。一方、文字列など他のデータ型を添え字のように使用できる配列を連想配列という。
固定長配列
決まった要素数しか格納できない配列を、固定長配列 (fixed-length array, fixed-size array) あるいは静的配列 (static array) と呼ぶ。
動的配列
要素数によって自動的にサイズが拡張される配列を、動的配列 (dynamic array, growable array, resizable array) と呼ぶ。メモリが許す限り、要素の末尾追加や途中挿入がいくらでもできる。標準ライブラリで提供されるもの(C++のstd::vector[1]、Javaのjava.util.ArrayList[2]、.NETのSystem.Collections.Generic.List[3][注釈 1]、Pythonのlist[4]、ECMAScriptのArray[5]など)と、言語に組み込まれているもの(PerlやDなど)がある。またPerlなど、言語によっては、最初に配列を生成する際に指定されたサイズからはみ出してアクセス(範囲外アクセス)しても、自動的に拡大されるような配列を持っているものもある。
動的配列の拡大などの場合には、最悪の場合、メモリ上の別の場所が確保されて、そこに全体をコピーする、というような時間のかかる操作が起きる可能性があるものもある(そのシステムの設計次第で、配列の内部にあるものが他からポインタで指されていて、それを更新できないなど、そういうことができない場合もある)。最悪計算量ではなく償却計算量でO(1)になれば良い、という考え方もある。
可変長配列
なおC言語では、下記のように、実行時に(整数定数式ではない)要素数を指定してスタック上に自動変数として確保することのできる静的配列を可変長配列 (variable-length array) と呼んでいる[6]。GCCに拡張として実装されていたが、C99以降で標準化された。この可変長配列は後から要素を追加したりすることはできない。
void func(size_t n) {
int data[n];
}
多次元配列
1次元だけではなく2次元・3次元などの多次元配列 (multidimensional array) を備える言語もある。 マトリックスやグリッドのような矩形構造を持ったデータ構造であることから、矩形配列 (rectangular array) と呼ばれることもある[7]。
C#やFORTRANなど、一部の言語には「真の」多次元配列があり、a[i, j]
などといったような構文でアクセスする。
C#による多次元配列の例を示す。
int[,] array2d = {
{0, 1, 2, 3},
{4, 5, 6, 7},
{8, 9, 10, 11},
};
System.Console.WriteLine(array2d[2, 3]);
C#には、後述するジャグ配列となる「配列の配列」もある。
C言語の場合
C言語は規格で多次元配列に関する言及があるが、実際にサポートされているのは「配列の配列」であって、真の多次元配列ではない[8]。次のようなコードのことを考えてみればわかる。
void f(int (*p_arr3)[3]) {
……
}
int main(void) {
int arr5_arr3[5][3];
f(arr5_arr3);
return 0;
}
ここで arr5_arr3
は「『intの3要素の配列』の5要素の配列」である。そして、関数fに渡される際には、C言語の「配列は引数として渡される際は、その先頭要素を指すポインタに縮退する」というルールにより、その先頭の「intの3要素の配列」を指すポインタがp_arr3
に渡される。
もし仮にC言語で真の多次元配列がサポートされているならば、それぞれ「intの5x3要素の配列」「『intの5x3要素』を指すポインタ」(あるいは、単にintを指すポインタに縮退するかもしれない)などがサポートされるはずだが、実際にはサポートされない。
Javaの場合
Javaの「配列の配列」はC言語よりもさらに緩く、Javaの型システムにおける「配列の配列」では、外側の配列は、内側の配列のサイズを固定しない(C言語では、内側の配列のサイズは固定である)。さらに、Javaにはプリミティブ型と参照型があり、参照型は一種のポインタだが、配列は参照型であるので、Javaの「配列の配列」は後述の「ジャグ配列」になっており、やはり真の多次元配列がサポートされているとは言えない。もちろん、1次元配列に対し多次元配列風にアクセスする機能を提供するようなクラスを実装することはできるが、それでは言語レベルで真の多次元配列がサポートされているとは言えない。
ジャグ配列
「配列の配列」の場合、内側の配列について、要素数が揃っていることを要求しないデータ構造であることもある。ジャグ配列 (jagged array)、不規則配列などと言う。これに対し、内側の配列の要素数が揃った配列を矩形配列 (rectangular array) などと言う。Javaにおける配列の配列はジャグ配列である。C#には前述の通り、「真の多次元配列」もあるが、それとは別に配列の配列もあり、そちらはJavaと同様のジャグ配列である。
Javaによるジャグ配列の例を示す。
int[][] numArr = new int[3][];
numArr[0] = new int[]{1, 2, 3};
numArr[1] = new int[]{4, 5, 6, 7};
numArr[2] = new int[]{8, 9};
System.out.println(numArr[1][1]);
C#によるジャグ配列の例を示す。
int[][] numArr = new int[3][];
numArr[0] = new int[]{1, 2, 3};
numArr[1] = new int[]{4, 5, 6, 7};
numArr[2] = new int[]{8, 9};
System.Console.WriteLine(numArr[1][1]);
要素のアドレスを指定するための参照の展開は、ジャグ配列では次元の数だけ必要なのに対し、矩形配列では1回で済む。また配列の領域を確保する際、ジャグ配列では次元ごとに領域確保を繰り返す必要があるのに対し、矩形配列では1回のnew演算子の使用で領域が確保できる。ただし矩形配列は全要素が収まる連続領域を確保しなければならず、疎行列などのまばらな配列には空間的オーバーヘッドが大きくなってしまうことから向いていない。また、.NET Frameworkの中間言語には1次元配列の要素アクセスに関する専用命令が存在するため、矩形配列よりもジャグ配列のほうが速度性能面で有利になるケースも存在する[9]。
C言語では、配列を指すポインタは、その配列のサイズを固定しなければならない。配列を指すポインタではなく、「『配列の先頭要素を指すポインタ』の配列」によって、次のようにしてジャグ配列のようなデータ構造を作ることができる。
int *numArr[3];
int tmp0[] = {1, 2, 3};
int tmp1[] = {4, 5, 6, 7};
int tmp2[] = {8, 9};
numArr[0] = tmp0;
numArr[1] = tmp1;
numArr[2] = tmp2;
printf("%d\n", numArr[1][1]); // print "5"
例示したように、「配列の配列」と同様の構文でアクセスできるが、データ構造としては異なっている[要追加記述]。当然、(生成されるコード[要追加記述]を読めばわかるが)意味的に違うものであって、混同してはならない。ましてや「多次元配列がサポートされていると考えるべき」などと考えるのは、混乱の元でしかない。
Iliffe vector
「ジャグ配列と同様な構造で実装された、多次元配列」という意味の、Iliffe vector という語がある("Iliffe" は、人名 John K. Iliffe に由来)。それに対し、連続した領域を多次元配列として扱うデータ構造を指す dope vector(en:Dope vector)という語がある。
脚注
注釈
- ^ リンクリストではなく、メモリ上で連続しているため、ランダムアクセスは定数時間のO(1)となる。
出典
- ^ “std::vector - cppreference.com”. ja.cppreference.com. 2024年4月12日閲覧。
- ^ “ArrayList (Java SE 21 & JDK 21)”. docs.oracle.com. 2024年4月12日閲覧。
- ^ dotnet-bot. “List<T> クラス (System.Collections.Generic)”. learn.microsoft.com. 2024年4月12日閲覧。
- ^ “リスト型 (list) - 組み込み型”. Python documentation. 2024年4月12日閲覧。
- ^ “Array - JavaScript”. 2024年4月12日閲覧。
- ^ ARR32-C. 可変長配列のサイズ引数は適切な範囲内にあることを保証する
- ^ 多次元配列・ジャグ配列 - Programming/.NET Framework/配列 - 総武ソフトウェア推進所
- ^ ISO/IEC 9899:1999 - n1256.pdf
- ^ 配列 - C# によるプログラミング入門 | ++C++; // 未確認飛行 C
配列(プログラム)
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2019/10/19 15:15 UTC 版)
コンピュータ言語において添字で指定できる一連の変数を配列(配列変数)と言うが、ひとつの配列で独立して指定できる添字の個数を配列の次元と言う。配列参照。
※この「配列(プログラム)」の解説は、「次元」の解説の一部です。
「配列(プログラム)」を含む「次元」の記事については、「次元」の概要を参照ください。
配列
「配列」の例文・使い方・用例・文例
- 名簿はアルファベット順の配列になっている
- InRecordの値を、複数の配列変数に設定します
- 私はその配列を決定する。
- を配列する.
- 項目はアルファベット順に配列されている.
- 著者別の配列.
- ABC 順に配列せよ.
- アルファベットに従って順番に配列される
- アルファベット順に、配列される(読者を開始するような)
- 文字の非字母文字式の配列
- 宇宙探査のための惑星の都合のいい配列
- 配列または式に減らす行為
- 水平の層に堆積または配列した
- 配列を擾乱する
- 新しい序列または配列に入れられる
- 親類の配列換えは、相互キャパシタンスとインダクタンスの効果を最小にするために送電線を置きます
- 要素の組み合わせや配列の集まりに関連する
- システムによって配列するか、システムまで減少する
- 配列が混合できるカナスタの形
- 無秩序と混乱を引き起こす、組織的な配列の乱れ
固有名詞の分類
品詞の分類
「配列」に関係したコラム
-
FX(外国為替証拠金取引)のチャート分析ソフトMT4(Meta Trader 4)での時刻表示は、MT4のダウンロード先にもよりますが、一般的には中央ヨーロッパ時間であることが多いようです。日本時間の...
- >> 「配列」を含む用語の索引
- 配列のページへのリンク