【问题标题】:Correct semantic usage of map正确使用地图的语义
【发布时间】:2017-06-13 15:31:23
【问题描述】:

我试图了解使用map 的语义正确方法。由于map 的行为方式与each 相同,因此您可以随意修改数组。但是我的同事告诉我,在应用map 之后,数组应该有 相同的顺序和相同的尺寸

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

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

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

【问题讨论】:

  • 那太好了,但很想听听为什么@sagarpandya82
  • 虽然mapeach 一样迭代,但它们是不同的工具。在实际使用中,我们看到人们在应该使用map 时尝试使用each,结果他们编写了更多代码。相反,他们会使用map 而不是each,最终也会编写太多代码。 map 用于更改值,each 用于循环它们。您可以强制重叠,但这会违反流程,因此请了解何时使用它们中的每一个。
  • 当你必须在地图之后使用 compact 时,很有可能你做错了什么,例如在块中使用不返回值的条件。地图块的每个循环都应该返回一个可用的值。如果您通过紧凑的方式丢弃值,那么您的代码会浪费 CPU 时间,您应该在将缩减集传递给 map 之前确定使用 selectreject 处理哪些值。
  • 换句话说,如果您想要的结果是一个带有@的数组,那么您的示例将是使用map的正确方法987654341@s 代替不等于 24 的值。由于这不是您想要的结果(正如需要 compact 所证明的那样),map 在这里是错误的选择。

标签: ruby


【解决方案1】:

思考这个:

array = [1,2,3,4]

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

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

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

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

多年来我一直在使用 map 和其他 Enumerator 方法,从未考虑过太多。

我建议考虑一下。正是这样的小事可以决定代码或系统的成败,而我们在编程时所做的一切都需要刻意完成,避免我们可以预见的所有负面影响。

【讨论】:

    【解决方案2】:

    在计算机科学领域,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”和后续 cmets 以获得进一步说明,并感谢 @meager 最初向我指出这一点。

    【讨论】:

    • 这是 Ruby 的一个很好的例子:非常灵活,但需要谨慎应用。感谢您的澄清。
    • @MaximFedotov 感谢您的接受,但可能是错误的选择。尽管有些用处,但我认为此答案不能解决您的问题和示例。我什至会说我给出的例子毫无意义。其他 cmets 和答案处理为什么 map 有时是错误的选择以及何时不使用它。
    • 我认为您应该对您的回答给予更多的信任。虽然 Tin Man 的回答很棒,而且看到 CPU 和内存利用率的角度也很有趣,但你的回答与我所问的完全一致。此外,@meager 对您的其他答案的评论也提供了一些额外的背景信息。所以我想保持你的回答被接受。
    猜你喜欢
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 2022-11-18
    • 2016-02-25
    • 2013-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多