"map"메소드는 Ruby에서 무엇을합니까?


250

저는 프로그래밍을 처음 사용합니다. 누군가가 할 일 .map을 설명 할 수 있습니까?

params = (0...param_count).map

9
질문 번에 질문을. map시퀀스에서 값을 변환하는 데 사용되는 열거 가능한 객체에서 발견되는 일반적인 "기능"방법입니다 (특별 고려 사항 포함). .....범위를 만드는 방법이 있습니다. 또한 REPL에 익숙해 지면 직접 사용해보십시오! :)

5
루비에 대한 REPL은 irb이고, 레일의 경우 레일입니다. c. REPL을 사용하면 언어 쉘 자체에 대해 직접 코드를 테스트 할 수 있습니다.
Gary

답변:


431

map메소드는 열거 가능한 객체와 블록을 가져 와서 각 요소에 대해 블록을 실행하여 블록에서 반환 된 각 값을 출력합니다 (원본 객체는 사용하지 않으면 변경되지 않습니다 map!):

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

Array그리고 Range열거 유형입니다. 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

3
예를 들어 speransky에게 감사드립니다. .map은 .each와 어떻게 다릅니 까?
bigpotato

2
아아. 따라서 .map은 실제로 배열을 변경하지만 .each는 배열을 반복하여 값에 액세스하면서 원래 배열은 그대로 유지합니까?
bigpotato

24
첫 문장 map이 마치 그 문장 처럼 묘사 되어있는 것은 일반 독자에게는 위험합니다map!
kaleidic

12
지도와 각각의 차이점을 보려면 IRB 창을 열고 다음 코드에서 y 및 z에 대한 결과를 확인하십시오. y = [1,2,3] .each {| x | x + 1}; z = [1,2,3] .map {| x | x + 1}
davej 2016

7
@Inquisitive : 'each'는 블록이 제공 될 때이를 호출하는 배열 (예 : [1,2,3])을 반환하고 'map'은 블록이 계산 한 값으로 채워진 새 배열을 반환합니다. 변수 ary = [1,2,3]을 설정하고 object_id인지 확인하십시오. 그런 다음 y = ary.each {| x | x + 1}; z = ary.map {| x | x + 1}. 이제 y와 z의 object_id를 확인하십시오. y는 ary와 동일한 object_id를 갖지만 (반환 된 ary마다) z는 다른 object_id를 갖습니다. map은 새로운 배열을 반환했기 때문입니다.
davej

66

map과 함께 select그리고 each내 코드에서 루비의 일꾼 중 하나입니다.

각 배열의 객체에 대해 작업을 실행하고 모두 같은 위치에 반환 할 수 있습니다. 예를 들어 숫자 배열을 1 씩 증가시키는 것이 있습니다.

[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"]

루비에서 데이터를 변환하려면 일련의 map작업이 필요합니다. Study map& select는 기본 라이브러리에서 가장 유용한 Ruby 메소드 중 일부입니다. 그들은만큼 중요합니다 each.

( map의 별칭이기도합니다 collect. 개념적으로 가장 적합한 것을 사용하십시오.)

더 유용한 정보 :

는 IF 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

해시의 경우 ( Enumerable개체 도 해시는 통역사를위한 특별 지침이있는 튜플의 배열입니다). 첫 번째 "파이프 매개 변수"가 키이고 두 번째는 값입니다.

{: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

irb에서는 작동하지 않습니다. 나는 NoMethodError: private method 'plusone' called for 1:Fixnum루비 1.9 / 1.8에서 루비 2와 '잘못된 수의 인수'를 얻 습니다. 어쨌든, 나는 람다를 사용했다 : plusone = ->(x) { x + 1 }기호 지정자를 꺼내십시오 : [1,2,3].map(&plusone).
tjmcewan 2016 년

1
흠 당신 같은 소리를 선언 private안에 당신이 전에 당신의 방법을 넣어 클래스의 당신의 방법을 넣어
boulder_ruby

네, 그렇습니다. 그렇지 않은 것을 제외하고. . :(이 두 번째로 일반 IRB의 클래스 O / w 직선 스크립트에 있었다 우선은 여기 내 사본입니다 / 당신의 코드를 붙여 넣기 : gist.github.com/tjmcewan/a7e4feb2976a93a5eef9을
tjmcewan

예, 코드에 나쁜 예를 넣었습니다. 죄송합니다. 수정 된 코드를 사용해보십시오. 그것은 지금 작동 ...
boulder_ruby

1
@boulder_ruby 클래스 메소드가 아닌 일반적인 메소드로 이것을 수행하는 방법이 있습니까?
tekknolagi

6

루비 2.4를 사용하면 transform_values레일에서 루비로 추출 된이 기능을 사용하여 동일한 작업을 수행 할 수 있습니다 .

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

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

4

0..param_count"param_count 이하"를 의미합니다. 0...param_count"param_count까지는 포함하지 않습니다"를 의미합니다.

Range#map를 반환하지 않고 Enumerable실제로 배열에 매핑합니다. 와 동일합니다 Range#to_a.


3

이 함수는 Enumerable-의 경우 각 항목에 기능을 "매핑"합니다 . 따라서 0에서 0까지의 모든 정수에 대해 한 번 전달 된 블록을 호출하고 param_count(독점-점에 대해 맞습니다) 각 반환 값을 포함하는 배열을 반환합니다.

에 대한 설명서는 다음과 같습니다 Enumerable#map. 또한 별칭이 collect있습니다.


이상하지만 Range#map실제로는 배열로 변환합니다.
Pedro Nascimento

1
@PedroNascimento : 응 ... 그게 내가 말한거야?
Ry-

죄송합니다. 자체적으로 호출 한지도가 Enumerable각각처럼을 반환하지 않았다는 것을 알지 못했습니다 . 나는 그렇게 생각했다.
Pedro Nascimento

2

맵은 열거 가능한 모듈의 일부입니다. "collect"와 매우 유사합니다. 예 :

  Class Car

    attr_accessor :name, :model, :year

    Def initialize (make, model, year)
      @make, @model, @year = make, model, year
    end

  end

  list = []
  list << Car.new("Honda", "Accord", 2016)
  list << Car.new("Toyota", "Camry", 2015)
  list << Car.new("Nissan", "Altima", 2014)

  p list.map {|p| p.model}

맵은 블록 매개 변수에 의해 리턴되는 배열을 반복하는 값을 제공합니다.


map은 collect와 정확히 동일합니다.
BKSpurgeon

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()}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.