PHPでは、 array_fill()は、指定された値で配列を埋めるための非常に便利な機能です。通常、アレイの初期化には、特にデフォルト値の配列をすばやく生成する必要がある場合に使用されます。ただし、多くの開発者は、array_fill()を使用して2次元配列を作成すると、一般的な誤解に陥る傾向があり、プログラムで予期しない動作につながります。この記事では、これらの一般的な間違いと、それらを正しく回避する方法について説明します。
質問を掘り下げる前に、 array_fill()の基本的な使用法を簡単に確認しましょう。
$filledArray = array_fill(0, 5, 'default');
// 結果: ['default', 'default', 'default', 'default', 'default']
この関数は、3つのパラメーターを受け入れます。
インデックスを開始する(インデックスが充填を開始するため)
配列の長さ(いくつかの要素で満たされています)
充填値
array_fill()を使用して、5行などの2次元配列を作成しようとすると、それぞれ3つのデフォルト値「デフォルト」がある、多くの開発者が次のコードを書きます。
$matrix = array_fill(0, 5, array_fill(0, 3, 'default'));
一見、この書き方は合理的に思えます。出力の結果も予想通りです。
[
['default', 'default', 'default'],
['default', 'default', 'default'],
['default', 'default', 'default'],
['default', 'default', 'default'],
['default', 'default', 'default']
]
しかし、問題は次のとおりです。これらのサブアレイは、実際には同じ配列への参照です!
つまり、サブアレイの1つの値を変更した場合です。
$matrix[0][0] = 'changed';
これにより、すべての行の最初の値が「変更」されます。
[
['changed', 'default', 'default'],
['changed', 'default', 'default'],
['changed', 'default', 'default'],
['changed', 'default', 'default'],
['changed', 'default', 'default']
]
これは、 Array_fill()が、 3番目のパラメーターが一度に新しい配列インスタンスを作成するのではなく、Arrayである場合、同じ配列への参照で満たされているためです。
この問題を解決するには、各サブアレイが独立したインスタンスであることを確認する必要があります。最も安全な方法は、ループを使用することです。
$matrix = [];
for ($i = 0; $i < 5; $i++) {
$matrix[$i] = array_fill(0, 3, 'default');
}
これにより、各行の配列が新しいコピーであり、互いに影響を与えないことが保証されます。
2次元配列を作成する関数をカプセル化する場合は、関数の外側のサブアレイを作成してから再利用しないように注意してください。例えば:
エラーデモンストレーション:
function createMatrix($rows, $cols, $defaultValue) {
$rowTemplate = array_fill(0, $cols, $defaultValue);
return array_fill(0, $rows, $rowTemplate);
}
この問題は上記と同じで、すべての行は同じ$ rowtemplateを参照しています。 1つの行を変更すると、すべての行に影響します。
正しい書き込み:
function createMatrix($rows, $cols, $defaultValue) {
$matrix = [];
for ($i = 0; $i < $rows; $i++) {
$matrix[] = array_fill(0, $cols, $defaultValue);
}
return $matrix;
}
オンラインで塗りつぶされた質問生成ツール( https://m66.net/tools/quiz-generatorなど)を作成しているとしたら、各ボックスのデフォルト値がnullである空白の質問ボードを作成する必要があります。
$questionBoard = [];
for ($i = 0; $i < 10; $i++) {
$questionBoard[] = array_fill(0, 5, null);
}
このアプローチは、質問ボード全体で誤ってメモリを共有することを避けることができ、ユーザーの相互作用やその後のロジックのバグを引き起こすことができます。
array_fill()は効率的なツールですが、ネストされた配列(2次元または多次元)に関しては、共有参照に注意する必要があります。ループを使用して、各サブアレイが新しいインスタンスであることを確認することにより、より堅牢で予測可能なデータ構造を構築できます。
PHPの価値と参照メカニズムを理解することは、この問題を回避するだけでなく、大規模なプロジェクトで複雑なアレイ構造に対処する能力を向上させることにも役立ちます。