【问题标题】:Difference between array_filter() and array_map()? [duplicate]array_filter() 和 array_map() 之间的区别? [复制]
【发布时间】:2013-11-11 00:17:53
【问题描述】:

我查看了 web 中的类似主题以及堆栈溢出,但我可以清楚地了解这个主题。 Difference between array_map, array_walk and 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_map 实现array_filter 的功能吗?。

【问题讨论】:

    标签: php arrays associative-array


    【解决方案1】:

    array_filterarray_maparray_walk 这三个都使用回调函数循环遍历数组,其方式与 foreach 循环遍历 $array 使用 $key 的方式大致相同 => @ 987654327@对。
    在这篇文章中,我将引用传递给上述函数的原始数组$array,循环中当前项目的索引$key,以及值循环中的当前项,如$value

    array_filter 类似于 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 另一方面,接受多个数组作为参数。 如果指定了一个数组,则循环中当前项的 $value 被发送到回调。 如果使用两个或多个数组,则所有数组都需要首先通过array_values,如documentation中所述:

    如果数组参数包含字符串键,则返回数组 当且仅当恰好传递一个数组时才会包含字符串键。 如果传递了多个参数,则返回的数组总是有 整数键

    第一个数组被循环,它的值作为它的第一个参数传递给回调,如果指定了第二个数组,它也将被循环,它的值将作为第二个参数发送给回调,依此类推-on 等每个附加参数。
    如果数组的长度不匹配,则使用最大的数组,如documentation中所述:

    通常在使用两个或多个数组时,它们的长度应该相等 因为回调函数是并行应用的 对应的元素。如果数组长度不等,则较短 那些将用空元素扩展以匹配 最长。

    每次调用回调时,都会收集返回值。 仅在使用一个数组时保留键,并且 array_map 返回结果数组。 如果使用两个或更多数组,则键会丢失,而是返回一个填充有回调结果的新数组。 array_map 只向回调发送当前项目的 $value 而不是它的 $key。 如果您还需要密钥,可以将array_keys($array) 作为附加参数传递,然后回调将同时接收 $key 和 $value。
    但是,当使用多个数组时,原始键将以与 array_values 丢弃键的方式大致相同的方式丢失。 如果需要保留密钥,可以使用array_keys从原始数组中获取密钥,使用array_valuesarray_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_walkforeach($array as $key=&gt;$value) 非常相似,因为回调是同时发送一个键和一个值。如果您想将第三个参数直接传递给回调,它还接受一个可选参数。
    array_walk 返回一个布尔值,指示循环是否成功完成。
    (我还没有找到它的实际用途)
    请注意,array_walk 不使用回调的返回。 由于 array_walk 返回一个布尔值,为了让 array_walk 影响某些东西, 您需要引用 &$value 以便您可以修改或使用全局数组。 或者,如果您不想污染全局范围,可以使用 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 与 SQL 查询的类比真的让我很清楚,谢谢。在我使用 PHP 的 10 多年中,我几乎很少使用任何内置数组函数,所以我现在花时间去探索它们,所以这些例子很好。我真的认为很多 PHP 开发人员很难理解所有的数组函数,这让我想到了一篇很好的详细博客文章来涵盖所有 PHP 数组函数。您有兴趣为这样的博客文章投稿吗?
    • 你应该添加array_reduce
    【解决方案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_filterarray_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
          )
          

          【讨论】:

            猜你喜欢
            • 2011-03-26
            • 2014-11-01
            • 2013-07-01
            • 1970-01-01
            • 2012-02-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-08
            相关资源
            最近更新 更多