2013-02-20 6 views
3

,곱셈 기호는 무엇을합니까? 예상했던대로, 다음 스크립트를 삽입하여 특히

  • puts (1..5).inject {|x, y| x * y}
  • puts (1..5).inject(:*)
  • ,

모두 출력 120있다.

confused_ruby_map_inject.rb:1:in `map': wrong number of arguments(1 for 0) (ArgumentError) 
    from confused_ruby_map_inject.rb:1:in `<main>' 
: 그러나

, 스크립트가

print [[1,2], [3,4], [5,6]].map {|x, y| x * y} 

출력을

[2, 12, 30] 
예상대로

하지만 스크립트를 가지고

print [[1,2], [3,4], [5,6]].map(:*) 

ArgumentError를 제기

:*의 기능은 무엇이며, 두 번째 스크립트 세트를 사용하여 원하는 결과를 얻으려면 무엇이 가장 간결한 방법입니까?

답변

5

inject()은 블록 또는 심볼을 취할 수 있지만 map()은 항상 블록을 사용합니다. 나는 당신의 일 map()가 간결하다고 생각합니다.

:*은 곱셈 방법의 심볼 이름입니다.

업데이트 : 실제로, 비록 내가 당신의 map() 괜찮 작동 생각하지만, 당신을 위해 무엇을 찾고있을 수도 것은 고전적인지도 축소/인 것 같다 이상 :

[[1,2], [3,4], [5,6]].map{|a| a.reduce(:*)} 
+0

감사 (+1)! 명시 적으로 블록을 작성하는 것 이외의 다른 방법으로,'*'와 같은 기존의 메소드를 블록이나 proc로 변환 할 수 있습니까? 'map (to_proc (*))'과 같은 것? – Cam

+0

글쎄, 당신은 심볼을': *. to_proc'을 가진 proc로 변환 할 수 있지만,이 경우에는 그 우아한 사용법이 마음에 들지 않습니다. 내가 생각하는 옷장은 고전적인 map/reduce :'[[1,2], [3,4], [5,6]]입니다.지도 {| a | a.reduce (: *)}'. –

+0

다시 돌아와서 다른 옵션을 둘러 보았을 때 실제로 map/reduce는 기본적으로 내가 원하는 것에 가장 근접한 해결책이라는 것입니다. 당신의 도움을 주셔서 감사합니다! – Cam

2

당신은 그것을 할 수 다음과 같은 방법 : 여기

[[1,2], [3,4], [5,6]].collect{|t| t.inject(:*)}

당신이 분사가 어떻게 작동하는지 볼 수 있습니다 Enumerable Doc's

감사합니다.

2

inject에는 특수 구문이 있습니다. 당신은 앰퍼샌드를 사용하여지도에 가까이 갈 수 다음 *-method 인수 (문자열 또는 정수 중 하나를) 선택하지,이 걸리기 때문에

print [[1,2], [3,4], [5,6]].map(&:first) #=>[1, 3, 5] #note the ampersand 

print [[1,2], [3,4], [5,6]].map(&:*)  #=>in `*': wrong number of arguments(0 for 1) (ArgumentError) 

오류입니다. [1,2].*을 실행할 때 발생하는 오류입니다. *가하는 일의

데모 :

p [1,2]*2  #=> [1, 2, 1, 2] 
p [1,2]*' and ' #=> "1 and 2"