2013-10-31 20 views
10

ウェブでも同様のトピックを調べましたが、スタックオーバーフローはありましたが、これを私の頭の中にはっきりと入れることができました。 Difference between array_map, array_walk and array_filterarray_filter()とarray_map()の違いは?

<?php 
error_reporting(-1); 

$arr = array(2.4, 2.6, 3.5); 

print_r(array_map(function($a) { 
    $a > 2.5; 
},$arr)); 

print_r(array_filter($arr, function($a){ 
    return $a > 2.5; 
})); 

?> 

上記のコードは私その値> 2.5で濾過配列を返します。 array_maparray_filterの処理を達成できますか?

+0

文書をお読みになりましたか? – sectus

答えて

16

すべての3つ、array_filterarray_map、及びarray_walk、ほとんど同じ方法で配列をループにforeachループをコールバック関数を使用$arrayをループします。$key =>$valueのペアを使用します。
この投稿の期間中、私は元の配列を参照して、$array、ループ内の現在の項目のインデックスとして、$keyと現在の項目の値を渡しますループ内では、$valueとなります。

は、レコードを選択しても変更しないMySQLのSELECTクエリに似ています。
array_filterのコールバックは、現在のループアイテムの$valueに渡され、コールバックが返すものはブール値として扱われます。
真の場合の場合、その項目は結果に含まれます。
の場合、その項目は結果から除外されます。
したがって、あなたが行う可能性があります:

<pre><?php 
$users=array('user1'=>array('logged_in'=>'Y'),'user2'=>array('logged_in'=>'N'),'user3'=>array('logged_in'=>'Y'),'user4'=>array('logged_in'=>'Y'),'user5'=>array('logged_in'=>'N')); 
function signedIn($value) 
{ 
    if($value['logged_in']=='Y')return true; 
    return false; 
} 
$signedInUsers=array_filter($users,'signedIn'); 
print_r($signedInUsers);//Array ([user1] => Array ([logged_in] => Y) [user3] => Array ([logged_in] => Y) [user4] => Array ([logged_in] => Y)) 
?></pre> 

array_map一方では、引数として複数の配列を受け入れます。 1つの配列が指定されている場合、ループ内の現在の項目の$値がコールバックに送信されます。 2つの以上のアレイが使用されている場合は、すべての配列がdocumentationで述べたように最初array_valuesを通過する必要があります

配列引数が文字列のキーが含まれている場合にのみ、その後、返される配列 は、文字列キーが含まれています厳密に1つの配列が渡された場合。 つ以上の引数が返される配列は常に 整数キー

最初の配列を介してループし、その値は、その最初のパラメータとしてコールバックに渡され、二番目の配列は、それを指定された場合を持つ次に渡された場合もループされ、その値は2番目のパラメータとしてコールバックに送信され、その他の各パラメータについても同様に送信されます。 documentationで述べたよう
配列の長さが一致しない場合は、最大のアレイが、使用されている:

二つ以上の配列を使用する場合、通常、それらは、コールバック関数ので等しい長 であるべきです対応する要素に並列に適用されます。配列の長さが等しくない場合は、 のものが空の要素で拡張され、 の長さに最も一致します。

コールバックが呼び出されるたびに、戻り値が収集されます。 キーは1つの配列で作業する場合にのみ保持され、array_mapは結果の配列を返します。 2つ以上の配列を操作している場合、キーは失われ、代わりにコールバック結果が格納された新しい配列が返されます。 array_mapは、$キーではなく現在の項目の$値だけをコールバックに送信します。 キーが必要な場合は、追加の引数としてarray_keys($array)を渡すことができます。コールバックには、$ keyと$ valueの両方が渡されます。
しかし、複数の配列を使用する場合、array_valuesがキーを破棄するのとほぼ同じ方法で元のキーが失われます。 キーを保存する必要がある場合は、元の配列のキーを取得するのにarray_keysを使用し、array_mapの結果から値を取得するか、array_mapの結果を直接使用することができます。次にarray_combineを使用して2つを結合します。

このようにあなたが行う可能性があります:コールバックがキーと値の両方を送信することで

<pre><?php 
$array=array('apple'=>'a','orange'=>'o'); 
function fn($key,$value) 
{ 
    return $value.' is for '.$key; 
} 
$result=array_map('fn',array_keys($array),$array); 
print_r($result);//Array ([0] => a is for apple [1] => o is for orange) 
print_r(array_combine(array_keys($array),$result));//Array ([apple] => a is for apple [orange] => o is for orange) 
?></pre> 

array_walkforeach($array as $key=>$value)と非常によく似ています。コールバックに3番目の引数を直接渡す場合は、オプションの引数も受け入れます。
array_walkは、ループが正常に完了したかどうかを示すブール値を返します。
(私はまだそれを実際に使用しています)
注意:array_walkはコールバックの戻り値を使用しません。 array_walkがブール値を返すので、array_walkが何かに影響を与えるためには、を参照する必要があります。& $ valueを参照する必要があります。グローバル配列を変更または使用する必要があります。 また、グローバルスコープを汚染したくない場合は、array_walkのオプションの第3引数を使用して、書き込む変数への参照を渡すことができます。

<pre><?php 
$readArray=array(1=>'January',2=>'February',3=>'March',4=>'April',5=>'May',6=>'June',7=>'July',8=>'August',9=>'September',10=>'October',11=>'November',12=>'December'); 
$writeArray=array(); 
function fn($value,$key,&$writeArray) 
{ 
    $writeArray[$key]=substr($value,0,3); 
} 
array_walk($readArray,'fn',&$writeArray); 
print_r($writeArray);//Array ([1] => Jan [2] => Feb [3] => Mar [4] => Apr [5] => May [6] => Jun [7] => Jul [8] => Aug [9] => Sep [10] => Oct [11] => Nov [12] => Dec) 
?></pre> 
+0

本当に素晴らしい説明。 array_filterのSQLクエリとの類推は、本当に感謝してくれました。私の10年以上のPHPでは、組み込みの配列関数を使用することはめったにありませんでしたので、これらの例をすべて調べる時間がかかりました。私は本当に多くのPHP開発者がすべての配列関数を理解するのに苦労していると思っています。あなたはそのようなブログ記事に貢献したいですか? – JasonDavis

+0

'array_reduce'を追加してください – jcuenod

3

array_filterは、関数がtrueを返す元の配列の要素を返します。

array_mapは、元の配列のすべての要素に対して関数を呼び出した結果の配列を返します。

私はあなたがもう一方の代わりに1つを使用できる状況を考えることはできません。

0
  • array_mapには副次的な影響はありませんが、array_mapは引数を変更しません。
  • array_map/array_walkの結果の配列は、引数として 要素の同じ番号を持ちます。 array_filterは、フィルタリング関数に従って配列の要素のサブセットのみを選択します。それは キーを保持します。

例:

<pre> 
<?php 

$origarray1 = array(2.4, 2.6, 3.5); 
$origarray2 = array(2.4, 2.6, 3.5); 

print_r(array_map('floor', $origarray1)); // $origarray1 stays the same 

// changes $origarray2 
array_walk($origarray2, function (&$v, $k) { $v = floor($v); }); 
print_r($origarray2); 

// this is a more proper use of array_walk 
array_walk($origarray1, function ($v, $k) { echo "$k => $v", "\n"; }); 

// array_map accepts several arrays 
print_r(
    array_map(function ($a, $b) { return $a * $b; }, $origarray1, $origarray2) 
); 

// select only elements that are > 2.5 
print_r(
    array_filter($origarray1, function ($a) { return $a > 2.5; }) 
); 

?> 
</pre> 

結果:

Array 
(
    [0] => 2 
    [1] => 2 
    [2] => 3 
) 
Array 
(
    [0] => 2 
    [1] => 2 
    [2] => 3 
) 
0 => 2.4 
1 => 2.6 
2 => 3.5 
Array 
(
    [0] => 4.8 
    [1] => 5.2 
    [2] => 10.5 
) 
Array 
(
    [1] => 2.6 
    [2] => 3.5 
) 
1

array_mapは、それぞれにコールバック関数を適用した後、配列のすべての要素を含む配列を返します:

このようにあなたが行う可能性があります。アレイの

$a=array("a","bb","ccd","fdjkfgf"); 
$b = array_map("strlen",$a); 
print_r($b); 

//output 
Array 
(
    [0] => 1 //like strlen(a) 
    [1] => 2 //like strlen(bb) 
    [2] => 3 //like strlen(ccd) 
    [3] => 7 //like strlen(fdjkfgf) 
) 

array_filter戻り、一方のみの要素の機能は

例えば真である:例えば

アレイから取り除く "BB" 値も

function test_filter($b) 
    { 
    if($b=="bb") 
     { 
      return false; 
     } 
    else 
     { 
      return true; 
     } 
    } 
$a=array("a","bb","ccd","fdjkfgf"); 
$b = array_filter($a,"test_filter"); 
print_r($b); 

//output 
Array 
(
    [0] => a  //test_filter() return true 
    [2] => ccd //test_filter() return true 
    [3] => fdjkfgf //test_filter() return true 
) 
1

array_filter呼び出し可能(関数)が渡されることなく動作しますが、array_mapでは必須です。

$v = [true, false, true, true, false]; 
$x = array_filter($v); 

var_dump($x); 
array(3) { [0]=> bool(true) [2]=> bool(true) [3]=> bool(true) } 

array_walkarray_filterarray_mapがアレイは参照によって渡されるため、これは、新しい配列を返す一方、渡された実際の配列を変化させます。

関連する問題