纠正地图的语义用法

时间:2017-06-13 15:31:23

标签: ruby

我试图了解使用map的语义上正确的方法。由于map的行为方式与each相同,因此您可以按照自己喜欢的方式修改数组。但是我的同事告诉我,在应用map之后,数组应该有 相同的订单和相同的尺寸

例如,这意味着使用地图返回更新的数组将不是使用map的正确方法:

array = [1,2,3,4]
array.map{|num| num unless num == 2 || num == 4}.compact

我多年来一直在使用map和其他Enumerator方法,并且从未考虑过这个问题。非常感谢经验丰富的Ruby开发人员的建议。

2 个答案:

答案 0 :(得分:4)

在计算机科学中,map根据Wikipedia

  

在许多编程语言中,map是更高阶的名称   将给定函数应用于列表的每个元素的函数,   以相同的顺序返回结果列表

此语句暗示map的返回值应该具有相同的长度(因为我们将函数应用于每个元素)。返回元素的顺序相同。因此,当您使用map时,这是读者所期望的。

如何使用map

arr.map {|i| arr.pop } #=> [3, 2]

这显然违背了map的意图,因为我们返回了不同数量的元素,它们甚至不是原始的应用顺序。所以不要像这样使用map。见" How to use ruby's value_at to get subhashes in a hash"以及随后的评论进一步澄清,并感谢@meager最初指出这一点。

答案 1 :(得分:4)

默想:

array = [1,2,3,4]

array.map{|num| num unless num == 2 || num == 4} # => [1, nil, 3, nil]
    .compact # => [1, 3]

中间值是一个大小相同的数组,但它包含不需要的值,强制使用compact。这样做的后果是浪费CPU时间生成零值,然后删除它们。此外,内存被浪费生成另一个阵列,当它不应该是相同的大小。想象一下处理数组中数千个元素的循环中的CPU和内存成本。

相反,使用正确的工具可以清理代码并避免浪费CPU或内存:

array.reject { |num| num == 2 || num == 4 } # => [1, 3]
  

我多年来一直在使用地图和其他枚举器方法,从来没有想过这么多。

我建议考虑一下。这样的小事可以创建或破坏代码或系统,以及我们在编程需要刻意完成时所做的一切,避免我们可以预见的所有负面副作用。