Разница между 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_filter не с array_map?.

5 ответов


все три, array_filter, использование array_map и array_walk, используйте функцию обратного вызова для цикла через массив примерно так же foreach петли петли через $array используя $key =>$value пар.
На протяжении этого поста я буду ссылаться на исходный массив, переданный вышеупомянутым функциям, как $array индекс текущего элемента в петле, как $key и значение текущего элемента в петле, как $value.

array_filter сравнивается с запросом выбора MySQL, который выбирает записи, но не изменяет их.
обратный вызов array_filter передается $value элемента текущего цикла и все, что возвращает обратный вызов, рассматривается как логическое значение.
Если правда этот пункт включен в результаты.
Если 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 С другой стороны можно несколько массивов в качестве аргументов. Если указан один массив, $value текущего элемента в цикле отправляется на обратный вызов. Если используются два или более массивов, все массивы должны сначала быть переданы через array_values, как указано в документация:

если аргумент array содержит строковые ключи, то возвращаемый массив будет содержать строковые ключи, если, и только если прошел ровно один массив. Если передается более одного аргумента, то возвращаемый массив всегда имеет целочисленные ключи

первый массив зацикливается, и его значение передается обратному вызову в качестве первого параметра, и если указан второй массив, он также будет зацикливаться, и его значение будет быть отправленным в качестве 2-го параметра в обратный вызов и так далее и тому подобное для каждого дополнительного параметра.
Если длина массивов не совпадает, используется самый большой массив, как указано в документация:

обычно при использовании двух или более массивов, они должны быть одинаковой длины поскольку функция обратного вызова применяется параллельно с соответствующий элемент. Если массивы имеют неравную длину, короче будет продлен с пустыми элементы, соответствующие длине самый длинный.

каждый раз, когда вызывается обратный вызов, собирается возвращаемое значение. Ключи сохраняются только при работе с одним массивом, а array_map возвращает результирующий массив. При работе с двумя или более массивами ключи теряются и вместо них возвращается новый массив, заполненный результатами обратного вызова. array_map отправляет только обратный вызов $value текущего элемента, а не его $key. Если вам нужен ключ, а также, вы можете пройти array_keys($array) в качестве дополнительного аргумента обратный вызов получит как $ key, так и $value.
Однако при использовании нескольких массивов исходные ключи будут потеряны так же, как array_values отбрасывает ключи. Если вам нужны ключи для сохранения, вы можете использовать array_keys чтобы захватить ключи от исходного массива и array_values, чтобы захватить значения из результата использование array_map, или просто используйте результат использование array_map напрямую поскольку он уже возвращает значения, объедините их с помощью array_combine.

таким образом вы могли бы сделать:

<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, чтобы у вас было то, что нужно изменить или использовать глобальный массив. Кроме того, если вы не хотите загрязнять глобальную область, необязательный 3-й аргумент array_walk можно использовать для передачи ссылки на переменную, с которой нужно писать к.

таким образом вы могли бы сделать:

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

array_filter возвращает элементы исходного массива, для которых функция возвращает true.

array_map возвращает массив результатов вызова функции на все элементы исходного массива.

Я не могу придумать ситуацию, когда вы могли бы использовать один вместо другого.


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 возврат новых массивов, это потому, что массив передается по ссылке.


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
)

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