Ruby中的“map”方法做了什么?

时间:2012-08-23 03:54:25

标签: ruby map range enumeration

我是编程新手。有人可以解释一下.map会做什么:

params = (0...param_count).map

8 个答案:

答案 0 :(得分:419)

map方法接受一个可枚举的对象和一个块,并为每个元素运行块,输出块中的每个返回值(原始对象不变,除非你使用map!)

[1, 2, 3].map { |n| n * n } #=> [1, 4, 9]

ArrayRange是可枚举的类型。带有块的map返回一个数组。 map!改变原始数组。

这在哪里有用,map!each之间有什么区别?这是一个例子:

names = ['danil', 'edmund']

# here we map one array to another, convert each element by some rule
names.map! {|name| name.capitalize } # now names contains ['Danil', 'Edmund']

names.each { |name| puts name + ' is a programmer' } # here we just do something with each element

输出:

Danil is a programmer
Edmund is a programmer

答案 1 :(得分:61)

map以及selecteach是我代码中Ruby的主力之一。

它允许您对每个数组的对象运行操作,并将它们全部返回到同一位置。一个例子是将数字数组增加一个:

[1,2,3].map {|x| x + 1 }
#=> [2,3,4]

如果你可以在数组的元素上运行单个方法,你可以像这样的速记样式:

  1. 要使用上面的示例执行此操作,您必须执行此类操作

    class Numeric
      def plusone
        self + 1
      end
    end
    [1,2,3].map(&:plusone)
    #=> [2,3,4]
    
  2. 为了更简单地使用&符号快捷键技术,让我们使用另一个例子:

    ["vanessa", "david", "thomas"].map(&:upcase)
    #=> ["VANESSA", "DAVID", "THOMAS"]
    
  3. 在Ruby中转换数据通常涉及一系列map操作。研究map& select,它们是主库中最有用的Ruby方法之一。它们与each一样重要。

    map也是collect的别名。在概念上使用最适合您的任何内容。)

    更多有用的信息:

    如果您运行的Enumerable对象eachmap包含一组可枚举元素(哈希值,数组),则可以在块管道中声明每个元素像这样:

    [["audi", "black", 2008], ["bmw", "red", 2014]].each do |make, color, year|
      puts "make: #{make}, color: #{color}, year: #{year}"
    end
    # Output:
    # make: audi, color: black, year: 2008
    # make: bmw, color: red, year: 2014
    

    对于Hash(也是一个Enumerable对象,Hash只是一个元组数组,带有解释器的特殊指令)。第一个“管道参数”是键,第二个是值。

    {:make => "audi", :color => "black", :year => 2008}.each do |k,v|
        puts "#{k} is #{v}"
    end
    #make is audi
    #color is black
    #year is 2008
    

    回答实际问题:

    假设params是一个哈希值,这将是映射它的最佳方式:使用两个块参数而不是一个来捕获密钥&哈希中每个解释的元组的值对。

    params = {"one" => 1, "two" => 2, "three" => 3}
    params.each do |k,v|
      puts "#{k}=#{v}"
    end
    # one=1
    # two=2
    # three=3
    

答案 2 :(得分:5)

使用ruby 2.4你可以使用transform_values做同样的事情,这个功能从rails提取到ruby。

h = {a: 1, b: 2, c: 3}

h.transform_values { |v| v * 10 }
 #=> {a: 10, b: 20, c: 30}

答案 3 :(得分:4)

0..param_count表示“最多并包括param_count”。 0...param_count表示“最多但不包括param_count”。

Range#map不返回Enumerable,它实际上将其映射到数组。它与Range#to_a相同。

答案 4 :(得分:3)

它将一个函数“映射”到Enumerable中的每个项目 - 在这种情况下,是一个范围。因此,对于从0到param_count的每个整数,它会调用块传递一次(不包括 - 你对点是正确的)并返回一个包含每个返回值的数组。

Here's the documentation for Enumerable#map.它还有一个别名collect

答案 5 :(得分:2)

Map是可枚举模块的一部分。非常类似于“收集”例如:

spark.sql.columnNameOfCorruptRecord

Map提供迭代通过块参数返回的数组的值。

答案 6 :(得分:0)

#each

#each为数组中的每个元素运行一个函数。以下两个代码摘录是等效的:

x = 10
["zero", "one", "two"].each{|element|
    x++
    puts element
}
x = 10
array = ["zero", "one", "two"]

for i in 0..2
    x++
    puts array[i]
end

#map

#map将函数应用于数组的每个元素,并返回结果数组。以下是等效的:

array = ["zero", "one", "two"]
newArray = array.map{|element| element.capitalize()}
array = ["zero", "one", "two"]

newArray = []
array.each{|element|
    newArray << element.capitalize()
}

#map!

#map!类似于#map,但在适当位置修改了数组。以下是等效的:

array = ["zero", "one", "two"]
array.map!{|element| element.capitalize()}
array = ["zero", "one", "two"]
array = array.map{|element| element.capitalize()}

答案 7 :(得分:0)

对于任何需要可视化的人:

Map method example explained visually

Map that does nothing

Map that does even less

Map with a bang!

这里是完整的故事:

https://richstone.io/rubys-map-collect-methods-explained-visually/