ホームページ  >  記事  >  バックエンド開発  >  PHPの高度なトラバーサルと演算処理方法 array_PHPチュートリアル

PHPの高度なトラバーサルと演算処理方法 array_PHPチュートリアル

WBOY
WBOYオリジナル
2016-07-13 16:57:45914ブラウズ

foreach や for などのステートメントに基づく単純な配列走査については以前に説明しましたが、ここでは、開発に非常に役立つ、強力な実用的なパフォーマンスを備えた配列の高度な走査メソッドを紹介します。そしてより複雑です。

PHP の配列の処理は、この言語の最も魅力的な機能の 1 つと言えます。PHP は 70 を超える配列関連の関数をサポートしています。配列を反転したり、配列内に値が存在するかどうかを判断したり、配列を文字列に変換したり、配列のサイズを計算したりする場合は、既存の関数を実行するだけで実行できます。ただし、配列関連のタスクの中には、マニュアルで特定の機能を知っているだけでは解決できないものもあります。これらのタスクでは、問題を解決するには、PHP の本来の機能についての深い理解とある程度の想像力が必要です。 。 力。

多次元連想配列の並べ替え
PHP は、sort()、ksort()、asort() などのいくつかの配列ソート関数を提供しますが、多次元連想配列のソートは提供しません。


たとえば、次のような配列:

配列
(
[0] => 配列
(
[名前] =>チェス
[価格] => 12.99
)

[1] => 配列
(
[名前] =>チェッカーズ
[価格] => 9.99
)

[2] => 配列
(
[名前] => バックギャモン
[価格] => 29.99
)
)

配列を昇順に並べ替えるには、価格を比較する関数を自分で作成し、その関数をコールバック関数として usort() 関数に渡してこの関数を実装する必要があります。

コードは次のとおりです関数comparePrice($priceA, $priceB){

このプログラムフラグメントを実行すると、配列がソートされ、結果は次のようになります:

配列
(
[0] => 配列
(
[名前] =>チェッカーズ
[価格] => 9.99
)

[1] => 配列
(
[名前] =>チェス
[価格] => 12.99
)

[2] => 配列
(
[名前] => バックギャモン
[価格] => 29.99
)
)

配列を降順に並べ替えるには、comparePrice() 関数で 2 つの減算された数値の位置を交換するだけです。

逆の順序で配列を走査します
PHP の While ループと For ループは、配列を走査するために最も一般的に使用されるメソッドです。しかし、以下のような配列をどのように反復処理するのでしょうか?

配列
(
[0] => 配列
(
[名前] => ボード
[ゲーム] => 配列
(
[0] => 配列
(
[名前] = & gt; [価格] = > 12.99
)

[1] => 配列

(
[名前] = & gt; [価格] = >9.99
)
)
)
)

PHP 標準ライブラリには、コレクション用のイテレータ クラスがあり、これは、いくつかの異種データ構造 (ファイル システムやデータベース クエリ結果セットなど) を走査するために使用できるだけでなく、未知のネストされた配列を反復するためにも使用できます。サイズ。たとえば、上記の配列を走査するには、RecursiveArrayIterator イテレータを使用できます。

コードは次のとおりです
コードをコピー
$priceA['価格'] - $priceB['価格'];

を返します }

usort($games, '比較価格');

コードをコピー$iterator = 新しい RecursiveArrayIterator($games); iterator_apply($iterator, 'navigateArray', array($iterator));
関数 navigateArray($iterator) {

while ($iterator->valid()) {
if ($iterator->hasChildren()) {

NavigateArray($iterator->getChildren()); } その他 {

Printf("%s: %s", $iterator->key(), $iterator->current());
}
$iterator->next(); }
}



このコードを実行すると、次の結果が得られます:

名前: ボード
名前:チェス
価格: 12.99
名前:チェッカーズ
価格: 9.99

連想配列の結果をフィルタリングする
次の配列を取得したが、価格が $11.99 未満の要素のみを操作したいとします。

配列
(
[0] => 配列
(
[名前] =>チェッカーズ
[価格] => 9.99
)

[1] => 配列
(
[名前] =>チェス
[価格] => 12.99
)

[2] => 配列
(
[名前] => バックギャモン
[価格] => 29.99
)
)

array_reduce() 関数を使用して簡単に実装できます。

コードは次のとおりです コードをコピー

関数フィルターゲーム($game){
return ($game['price'] }

$names = array_filter($games, 'filterGames');

array_reduce() 関数は、コールバック関数を満たさないすべての要素をフィルターで除外します。この例のコールバック関数は filterGames です。価格が 11.99 より低い要素はすべて保持され、その他は削除されます。このコード スニペットの実行結果:

配列
(
[1] => 配列
(
[名前] =>チェッカーズ
[価格] => 9.99
)
)

オブジェクトを配列に変換する
要件の 1 つは、オブジェクトを配列形式に変換することです。この方法は思っているよりもはるかに簡単で、強制的に変換するだけで十分です。例:

コードは次のとおりです コードをコピー

クラスゲーム{
パブリック $name;
公開価格;
}

$game = 新しいゲーム();
$game->name = 'チェス';
$ゲーム->価格 = 12.99;

print_r(array($game));

この例を実行すると、次の結果が生成されます:

配列
(
[0] => ゲームオブジェクト
(
[名前] => チェス
[価格] => 12.99
)
)

オブジェクトを配列に変換すると、予期しない副作用が生じる可能性があります。たとえば、上記のコード スニペットでは、すべてのメンバー変数はパブリック型ですが、プライベート変数の戻り結果は異なります。別の例を次に示します:

コードは次のとおりです コードをコピー

クラスゲーム{
パブリック $name;
プライベート $_price;

パブリック関数 setPrice($price) {
$this->_price = $price;
}
}

$game = 新しいゲーム();
$game->name = 'チェス';
$game->setPrice(12.99);

print_r(array($game));このコード スニペットを実行します:

配列
(
[0] => ゲームオブジェクト
(
[名前] => チェス
[_price:ゲーム:プライベート] => 12.99
)
)

ご覧のとおり、区別するために、配列に保存されたプライベート変数のキーが自動的に変更されます。

配列の「自然な順序付け」
PHP の「英数字」文字列のソート結果は未定義です。たとえば、配列に多数の画像名が保存されているとします。

コードは次のとおりです コードをコピー

$arr = 配列(
0=>'madden2011.png',
1=>'madden2011-1.png',
2=>'madden2011-2.png',
3=>'madden2012.png'
);

この配列をどのようにソートしますか? sort() を使用して配列を並べ替えると、結果は次のようになります:

配列
(
[0] =>madden2011-1.png
[1] =>madden2011-2.png
[2] =>madden2011.png
[3] =>madden2012.png
)

これが望ましい場合もありますが、元の添字を保持したい場合はどうすればよいでしょうか?この問題を解決するには、自然な方法で配列を並べ替える natsort() 関数を使用できます。

コードは次のとおりです コードをコピー

$arr = 配列(
0=>'madden2011.png',
1=>'madden2011-1.png',
2=>'madden2011-2.png',
3=>'madden2012.png'
);

natsort($arr);
echo "

"; print_r($arr); echo "
";
?>

実行結果:

配列
(
[1] =>madden2011-1.png
[2] =>madden2011-2.png
[0] =>madden2011.png
[3] =>madden2012.png
)

トラバーサル中の値変更操作
引用演算子&
以下のコードの $array 配列を見てください。このように、$value の値がループ内で変更されると、$array 内の対応する要素の値が変更されます。

コードは次のとおりです コードをコピー

$array = array("A"=>1, "B"=>1, "C"=>1, "D"=>1);
foreach($array as &$value)
$値 = 2;
print_r($array);
?>

上記のコードの出力は次のとおりです:

配列 ( [A] => 2 [B] => 2 [C] => 2 [D] => 2 )
ご覧のとおり、$array の各キーに対応する値が 2 に変更されています。このアプローチは実際に機能しているようです。

キー値を使用して配列の要素を操作します
場合によっては、配列が相互に関連する要素を表す場合があります。これらの相互に関連する要素の 1 つが見つかって、他の要素にマークが付けられた場合、上記の参照は確実に機能しません。現時点では、これらの関連要素を変更するときは、対応するキー値を使用する必要があります。まずは試してみて、うまくいくかどうかを確認してください:

コードは次のとおりです コードをコピー

$array = array("A"=>1, "B"=>1, "C"=>1, "D"=>1);
foreach($array as $key => $value){
If($key == "B"){
$array["A"] = "変更";
$array["D"] = "変更";
print_r($array);
エコー '
';
}

If($value === "変更")
echo $value.'
';
}
print_r($array);
?>

出力を見ることについて心配する必要はありません。出力がどのようなものであるかを想像してください。変更された配列を出力し、「CHANGE」を出力して、変更された配列を再度出力します。そうですか?出力を見てみましょう!

配列 ([A] => CHANGE [B] => 1 [C] => 1 [D] => CHANGE )
配列 ( [A] => CHANGE [B] => 1 [C] => 1 [D] => CHANGE )
はぁ?どうしたの?私たちの変化はどこへ行ったのでしょうか?

私たちのアイデアによれば、$array が変更されたため、キー値「D」を持つ要素に移動すると、その新しい値「CHANGE」が出力されるはずです。しかし、現実は私たちが思っているものではありません。 PHP はここで何をしたのでしょうか?上記のコードを少し変更します。配列を出力する場合は「D」=>CHANGEが正しいので、2番目のif文の判定条件を変更しましょう:

コードは次のとおりです コードをコピー

$array = array("A"=>1, "B"=>1, "C"=>1, "D"=>1);
foreach($array as $key => $value){
If($key == "B"){
$array["A"] = "変更";
$array["D"] = "変更";
print_r($array);
エコー '
';
}

If($array[$key] === "変更")
echo $value.'
';
}
print_r($array);
?>

何が出力されると思いますか? $value は絶対に「CHANGE」と等しくありません。それは 1 に等しいですか?

コードは次のとおりです コードをコピー
配列 ([A] => CHANGE [B] => 1 [C] => 1 [D] => CHANGE )
1
配列 ( [A] => CHANGE [B] => 1 [C] => 1 [D] => CHANGE )

すると、確かに1ですね。

その理由は何ですか? PHP ドキュメントの foreach ページに目を向けると、突然次のことに気づきました。

注: 配列が参照されない限り、foreach は配列自体ではなく、指定された配列のコピーを操作します。 foreach は配列ポインターにいくつかの副作用をもたらします。リセットされない限り、foreach ループ中またはループ後に配列ポインターの値に依存しないでください。

foreach は指定された配列のコピーを操作することがわかります。不思議ではありませんが、$value の取得は機能しません。これを理解すると、上記の問題は解決されます。 foreachであれば、キーに応じて$arrayの要素を直接取り出して、さまざまな判定や代入操作を行うことができます。


まとめと拡張
PHP の配列走査および操作機能は確かに非常に強力ですが、もう少し複雑な問題の解決策はそれほど明らかではありません。実際、これはどの分野でも当てはまります。複雑な問題を解決するには、言語と文法が基本的な操作を提供します。開発者自身の思考、想像力、コード記述が必要です。

www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/631503.html技術記事 foreach や for などのステートメントに基づく単純な配列の走査については以前に説明しました。次に、これらの配列を実際に開くために使用する方法を紹介します。
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。