web-dev-qa-db-ja.com

array_filter()とarray_map()の違いは?

私はウェブの同様のトピックとスタックオーバーフローを調べましたが、これをはっきりと頭に入れることができました。 array_map、array_walk、array_filterの違い

<?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_filterarray_map?。

20
John Cooper

array_filterarray_map 、および array_walk の3つすべてで、コールバック関数を使用して、ほぼ同じ方法で配列をループします foreach ループは $ array を使用してループします $ key => $ value ペア。
この投稿の期間中、上記の関数に渡された元の配列を、ループ内の現在のアイテムのインデックスである $ array として参照します。 as $ key 、およびループ内の現在のアイテムの値、as $ value

array_filterは、レコードをSELECTするが、レコードを変更しないMySQLのSELECTクエリに例えられます。
array_filterのコールバックは、現在のループ項目の $ value に渡され、コールバックが返すものはすべてブール値として扱われます。
trueの場合、アイテムは結果に含まれます。
falseの場合、そのアイテムは結果から除外されます。
したがって、次のことを行うことができます。

_<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つの配列が指定されている場合、ループ内の現在のアイテムの$ valueがコールバックに送信されます。 2つ以上の配列を使用する場合は、 ドキュメント で説明されているように、最初にすべての配列をarray_valuesに渡す必要があります。

配列引数に文字列キーが含まれている場合、返される配列には、1つの配列が渡された場合に限り、文字列キーが含まれます。複数の引数が渡された場合、返される配列には常に整数キーが含まれます

最初の配列はループスルーされ、その値は最初のパラメーターとしてコールバックに渡されます。2番目の配列が指定されている場合は、それもループスルーされ、その値は2番目のパラメーターとしてコールバックに送信されます。追加のパラメータごとにこれ以降。
配列の長さが一致しない場合は、 ドキュメント で説明されているように、最大​​の配列が使用されます。

通常、2つ以上の配列を使用する場合、コールバック関数は対応する要素と並行して適用されるため、それらは同じ長さである必要があります。配列の長さが等しくない場合、短い配列は空の要素で拡張され、最も長い配列の長さに一致します。

コールバックが呼び出されるたびに、戻り値が収集されます。キーは1つの配列で作業する場合にのみ保持され、array_mapは結果の配列を返します。 2つ以上の配列で作業している場合、キーは失われ、代わりにコールバックの結果が入力された新しい配列が返されます。 array_mapは、コールバックに現在のアイテムの$ valueのみを送信し、$ keyは送信しません。キーも必要な場合は、追加の引数としてarray_keys($array)を渡すことができます。そうすると、コールバックは$ keyと$ valueの両方を受け取ります。
ただし、複数の配列を使用する場合、array_valuesがキーを破棄するのとほぼ同じ方法で、元のキーが失われます。キーを保持する必要がある場合は、 array_keys を使用して元の配列からキーを取得し、 array_values を使用して 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_walkは、コールバックにキーと値の両方が送信されるという点でforeach($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>
_
25
Ultimater

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_walkは渡された実際の配列を変更しますが、array_filterおよびarray_map新しい配列を返します。これは、配列が参照によって渡されるためです。

4

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

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

片方をもう片方の代わりに使うことができる状況は考えられません。

4
Barmar

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関数がtrueである配列の要素のみを返します

例:配列から「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
)
3
Dinesh
  • 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
)
0
Zeeshan