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

Ответ 1

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

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

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

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

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

Каждый раз, когда вызывается обратный вызов, возвращается возвращаемое значение. Клавиши сохраняются только при работе с одним массивом, а array_map возвращает результирующий массив. При работе с двумя или несколькими массивами ключи теряются, и вместо этого возвращается новый массив, заполненный результатами обратного вызова. array_map отправляет обратный вызов значение $текущего элемента, а не его $key. Если вам нужен ключ, вы можете передать array_keys($array) в качестве дополнительного аргумента, тогда обратный вызов получит как ключ $, так и значение $.
Однако при использовании нескольких массивов исходные ключи будут потеряны почти так же, как 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) тем, что обратный вызов отправляется как ключ, так и значение. Он также принимает необязательный аргумент, если вы хотите передать третий аргумент непосредственно обратному вызову.
array_walk возвращает логическое значение, указывающее, успешно ли завершен цикл.
(Мне еще предстоит найти практическое применение)
Обратите внимание, что array_walk не использует обратный вызов. Поскольку array_walk возвращает логическое значение, чтобы array_walk мог что-то повлиять, вам нужно указать значение & $, чтобы у вас было то, что нужно изменить или использовать глобальный массив. В качестве альтернативы, если вы не хотите загрязнять глобальную область видимости, необязательный третий аргумент 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>

Ответ 2

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

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

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

Ответ 3

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
)

Ответ 4

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

Ответ 5

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