数组映射、数组遍历和数组滤波器有什么区别?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (5)
  • 关注 (0)
  • 查看 (123)

到底有什么区别array_map,,,array_walkarray_filter我从文档中看到的是,您可以传递一个回调函数来对提供的数组执行一个操作。

他们做同样的事吗?

它们可以互换使用吗?

如果它们完全不同的话,我希望你能提供说明性的例子。

提问于
用户回答回答于

其他答案显示了数组之间的区别array_walk (就地修改)和数组array_map(返回修改副本)相当好。然而,他们并没有真正提到数组array_reduce,这是理解数组的一种有启发性的方法array_map和array_filter

array_reduce函数接受一个数组,一个双参数函数和一个“accumulator”,如下所示:

array_reduce(array('a', 'b', 'c', 'd'),
             'my_function',
             $accumulator)

数组的元素使用给定的函数一次一个地与累加器组合。上述调用的结果与执行以下操作相同:

my_function(
  my_function(
    my_function(
      my_function(
        $accumulator,
        'a'),
      'b'),
    'c'),
  'd')

如果你更愿意从循环的角度来思考,这就像执行以下操作:

function array_reduce($array, $function, $accumulator) {
  foreach ($array as $element) {
    $accumulator = $function($accumulator, $element);
  }
  return $accumulator;
}

这个循环版本清楚地说明了为什么我将第三个参数称为“accumulator”:我们可以使用它在每次迭代中积累结果。

这和数组有什么关系?array_map和array_filter?我们可以这样实施:

array_map($function, $array)    === array_reduce($array, $MAP,    array())
array_filter($array, $function) === array_reduce($array, $FILTER, array())

忽略数组的事实array_map和array_filter以不同的顺序接受它们的参数;这只是PHP的另一个怪癖。重要的一点是,除了我称之为$map和$filter的函数之外,右边的功能是相同的。那么,他们长什么样?

$MAP = function($accumulator, $element) {
  $accumulator[] = $function($element);
  return $accumulator;
};

$FILTER = function($accumulator, $element) {
  if ($function($element)) $accumulator[] = $element;
  return $accumulator;
};

如你所见,这两个函数都接受$accumulator并再次返回它。这些职能有两个不同之处:

  • $map将始终附加到$accumulator,但是$filter只在$function($Element)为真时才会这样做。
  • $filter追加原始元素,而$map追加$Function($Element)。

我们经常可以看到类似以下两个例子的代码:

// Transform the valid inputs
array_map('transform', array_filter($inputs, 'valid'))

// Get all numeric IDs
array_filter(array_map('get_id', $inputs), 'is_numeric')

如果$inputs很大,则效率很低,因为第一个调用(map或filter)将遍历$inputs并构建一个中间数组。这个中间数组直接传递到第二个调用中,该调用将再次遍历整个过程,然后需要垃圾收集中间数组。

我们可以通过利用这个数组的事实来摆脱这个中间数组。array_reduce 通过组合它们,我们只需在每个示例中遍历$inputs:

// Transform valid inputs
array_reduce($inputs,
             function($accumulator, $element) {
               if (valid($element)) $accumulator[] = transform($element);
               return $accumulator;
             },
             array())

// Get all numeric IDs
array_reduce($inputs,
             function($accumulator, $element) {
               $id = get_id($element);
               if (is_numeric($id)) $accumulator[] = $id;
               return $accumulator;
             },
             array())

让它们像PHP一样运行并不困难,但我觉得这些复杂的情况会使核心想法更难发现。

热门问答

腾讯云广州一区DNS变更,需要怎么操作?

思潮澎湃轻描淡写的生活,但思潮澎湃
推荐
我也收到相关的通知了,这里分享下~ 2019年1月31日,腾讯云将对广州地区旧的基础网络DNS服务器(10.225.30.181、10.225.30.223)进行下线。在此期间,腾讯云提供最新的DNS服务器供您更新使用。 我们建议您尽快将DNS服务器配置进行更新,并且我们为您提供...... 展开详请

快照容量与费用的比例?如何关闭停用?

帅的惊动我国计算机大神
推荐已采纳
快照已于2019年1月22日0时启动正式商业化进程,商业化后所有存量快照和新产生的快照将根据快照使用的存储容量进行收费。 在快照商业化后,腾讯云仍旧会在国内主要地域为用户提供一定量的免费额度。免费额度策略如下: 免费额度覆盖范围为中国大陆地域,中国香港及海外地域暂无免费快照额...... 展开详请

无服务器云函数的cron表达式问题?

腾讯云serverless团队

腾讯云 · 产品团队 (已认证)

腾讯云无服务器云函数SCF产品
推荐
https://cloud.tencent.com/document/product/583/9708#cron-.E8.A1.A8.E8.BE.BE.E5.BC.8F.E8.AF.AD.E6.B3.95.E4.B8.80.EF.BC.88.E6.8E.A8.E8.8D.90.E...... 展开详请

云服务器-intelS2 标准入门型 带独立ip么?

Eli Qiao

腾讯 · 高级工程师 (已认证)

腾讯云CVM后台高级研发工程师
推荐

购买时,可以配置wan网ip,也可以之后添加eip

购买云服务器后上面的是否配套有数据库(mysql, sql server)和Web服务器等?

西风

renzha.net · 站长 (已认证)

www.renzha.net
推荐已采纳

买了服务器自己安装配置数据库即可,也可以另外选购性能更高,更安全可靠的云数据库。

无服务器云函数添加触发方式以错误码9000失败?

腾讯云serverless团队

腾讯云 · 产品团队 (已认证)

腾讯云无服务器云函数SCF产品
推荐

实在抱歉,最近这两天由于广州区 api 网关集群的配置量已超上限,导致 api 网关无法新增服务。目前 api 网关的研发同学已经在紧急扩容广州区集群了。

所属标签

扫码关注云+社区