2013-10-31 10 views
10

Ich habe die ähnlichen Themen im Web als auch Stack-Overflow angeschaut, aber konnte mir das klar in den Kopf setzen. Difference between array_map, array_walk and array_filterUnterschied zwischen array_filter() und 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; 
})); 

?> 

Der obige Code gibt mir ein gefiltertes Array, dessen Wert> 2,5. Kann ich erreichen, was ein array_filter mit einem array_map tut ?.

+0

Haben Sie die Dokumentation gelesen? – sectus

Antwort

16

All drei, array_filter, array_map und array_walk, verwenden, um eine Callback-Funktion durch eine Anordnung viel in der gleichen Art und Weise in einer Schleife foreach Schlaufen Schleife durch eine $array mit $key =>$value Paare.
Für die Dauer dieses Beitrags werde ich auf das ursprüngliche Array verweisen, das an die oben genannten Funktionen übergeben wird, wie $array, der Index des aktuellen Elements in der Schleife, als $key und der Wert des aktuellen Elements in der Schleife, wie $value.

wird mit der SELECT-Abfrage von MySQL verglichen, die Datensätze auswählt, aber sie nicht ändert.
Der Rückruf von array_filter wird an die $value des aktuellen Schleifenelements übergeben und was auch immer der Rückruf zurückgibt, wird als boolescher Wert behandelt.
Wenn wahr ist, ist das Element in den Ergebnissen enthalten.
Wenn false ist, wird der Artikel aus den Ergebnissen ausgeschlossen.
So könnten Sie tun:

<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 auf der anderen Seite akzeptiert mehrere Arrays als Argumente. Wenn ein Array angegeben ist, wird der Wert $ des aktuellen Elements in der Schleife an den Rückruf gesendet. Wenn zwei oder mehr Arrays verwendet werden, werden alle Arrays müssen zuerst durch array_values ​​übergeben werden, wie in der documentation erwähnt:

Wenn das Array Argument String-Schlüssel enthält dann die zurückgegebene Array Stringschlüssel enthalten wird, wenn und nur wenn genau ein Array übergeben wird. Wenn mehr als ein Argument übergeben werden dann die zurückgegebene Array hat immer integer Tasten

Das erste Array durchgeschleift wird, und sein Wert wird als erste Parameter an die Callback geführt, und wenn ein zweites Feld wird festgelegt, wird auch durchgeschleift und sein Wert wird als zweiter Parameter an den Rückruf und so weiter und so weiter für jeden zusätzlichen Parameter gesendet.
Wenn die Länge der Arrays nicht übereinstimmen, wird die größte Array verwendet wird, wie in den documentation erwähnt:

die Regel bei der Verwendung von zwei oder mehr Arrays, sollten sie gleich lang seine weil die Callback-Funktion parallel zu den entsprechenden Elementen angewendet wird. Wenn die Arrays ungleich lang sind, werden kürzere Elemente mit leeren Elementen erweitert, um die Länge des am längsten zu entsprechen.

Jedes Mal, wenn der Callback aufgerufen wird, wird der Rückgabewert erfasst. Die Schlüssel werden nur beibehalten, wenn mit einem Array gearbeitet wird, und array_map gibt das resultierende Array zurück. Wenn Sie mit zwei oder mehr Arrays arbeiten, gehen die Schlüssel verloren und stattdessen wird ein neues Array mit den Callback-Ergebnissen zurückgegeben. array_map sendet dem Callback nur den Wert $ des aktuellen Elements und nicht den Schlüssel $. Wenn Sie auch den Schlüssel benötigen, können Sie array_keys($array) als zusätzliches Argument übergeben, dann erhält der Callback sowohl den $ Schlüssel als auch den $ Wert.
Wenn Sie jedoch mehrere Arrays verwenden, gehen die ursprünglichen Schlüssel ungefähr genauso verloren wie array_values ​​die Schlüssel ablegt. Wenn Sie die Schlüssel erhalten möchten, können Sie array_keys verwenden, um die Schlüssel aus dem ursprünglichen Array und array_values die Werte aus dem Ergebnis array_map greifen, oder einfach das Ergebnis array_map direkt verwenden, da es bereits die Werte zurückgibt, dann kombinieren Sie die beiden mit array_combine.

So könnten Sie tun:

<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 zu foreach($array as $key=>$value), dass sehr ähnlich ist der Rückruf sowohl einen Schlüssel gesendet wird und einen Wert. Es akzeptiert auch ein optionales Argument, wenn Sie ein drittes Argument direkt an den Callback übergeben möchten.
array_walk gibt einen booleschen Wert zurück, der angibt, ob die Schleife erfolgreich abgeschlossen wurde.
(Ich habe noch eine praktische Verwendung dafür gefunden)
Beachten Sie, dass array_walk die Rückkehr des Rückrufs nicht verwendet. Da array_walk einen booleschen Wert zurückgibt, damit array_walk auf etwas wirkt, müssen Sie $ 0 Wert angeben, so dass Sie haben, was zu ändern oder ein globales Array zu verwenden. Wenn Sie den globalen Gültigkeitsbereich nicht verschmutzen möchten, können Sie alternativ das optionale dritte Argument von array_walk verwenden, um einen Verweis auf eine Variable zu übergeben, in die geschrieben werden soll.

So könnten Sie tun:

<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

wirklich tolle Erklärungen. Die array_filter-Analogie zur SQL-Abfrage hat es mir wirklich deutlich gemacht, danke. In meinen 10+ Jahren mit PHP habe ich ziemlich selten irgendwelche der eingebauten Array-Funktionen verwendet, daher nehme ich mir jetzt die Zeit, sie alle zu erkunden, damit diese Beispiele schön sind. Ich glaube wirklich, dass viele PHP-Entwickler Schwierigkeiten haben, alle Array-Funktionen zu verstehen, und gibt mir die Idee für einen ausführlichen Blogbeitrag, der alle PHP-Array-Funktionen abdeckt. Wären Sie daran interessiert, zu solch einem Blogartikel beizutragen? – JasonDavis

+0

sollten Sie 'array_reduce' hinzufügen – jcuenod

3

array_filter gibt die Elemente des ursprünglichen Arrays zurück, für die die Funktion true zurückgibt.

array_map gibt ein Array der Ergebnisse des Aufrufs der Funktion für alle Elemente des ursprünglichen Arrays zurück.

Ich kann nicht an eine Situation denken, wo Sie eine anstelle der anderen verwenden könnten.

0
  • array_map hat keine Nebeneffekte, während array_map seine Argumente niemals ändert.
  • Das resultierende Array von array_map/array_walk hat die gleiche Anzahl von Elementen als Argument (en); array_filter wählt nur eine Teilmenge der Elemente des Arrays gemäß einer Filterfunktion aus. Es tut die Schlüssel zu bewahren.

Beispiel:

<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> 

Ergebnis:

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 Gibt ein Array alle Elemente des Array, das nach jedem einzelnen die Callback-Funktion anwenden.

zum Beispiel:

$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) 
) 

während array_filter Rückkehr nur die Elemente der Matrix für die die Funktion wahr ist

Beispiel: Entfernen "bb" Wert von Array

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 auch funktioniert, ohne dass eine Callable (Funktion) übergeben wird, während dies für array_map zwingend erforderlich ist.

z.B.

$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 ändert die übergebenen tatsächliche Array, während array_filter und array_map neue Arrays zurück, ist dies, weil die Anordnung durch Referenz übergeben wird.