답변:
이 시도:
array.inject(0){|sum,x| sum + x }
(참고 : 0
기본 사례는 필요하기 때문에 0
빈 배열에 대신 반환됩니다 nil
)
array.inject(:+)
가 더 효율적입니다.
array.inject(:+)
Ruby 1.8.6에서 문제 를 일으키는 것 같습니다. 예외 "LocalJumpError : no block given"이 나타날 수 있습니다.
array.sum
에서 배열 값의 합계를 제공 할 수 있습니다.
reduce
의 별칭 인 을 사용하는 것을 선호합니다 . inject
array.reduce( :+ )
inject
대신 사용에 대해 경고합니다 reduce
.
또는 Ruby 1.9 방식으로 시도하십시오.
array.inject(0, :+)
참고 : 0
기본 사례가 필요 nil
하면 빈 배열에 반환됩니다.
> [].inject(:+)
nil
> [].inject(0, :+)
0
array.map(&:price).inject(0, :+)
조금 더 안전합니다. 빈 목록이 있으면 nil 대신 0 을 얻습니다 .
array.inject(0) { |sum, product| sum += product.price }
array.reduce(0, :+)
반면에 Reducearray.inject(0, :+)
라는 용어 는 MapReduce 프로그래밍 모델 의 등장과 함께보다 일반적인 용어가되었습니다 .
주입 , 축소 , 접기 , 누적 및 압축 은 모두 접기 기능 클래스와 동의어 입니다. 코드 기반에서 일관성이 가장 중요하지만 다양한 커뮤니티가 한 단어를 다른 단어보다 선호하는 경향이 있기 때문에 대안을 아는 것이 유용합니다.
map-reduce ververage를 강조하기 위해, 그 배열에서 끝나는 것을 조금 더 용서하는 버전이 있습니다.
array.map(&:to_i).reduce(0, :+)
추가적인 관련 자료 :
reduce
합니다. 기능의 기능에 대해 더 inject
많이 말하지만 훨씬 더 시원하게 들립니다.
reduce
및 map
고차 함수는 맵리 듀스 앞선한다. 영감은 다른 방식으로 진행됩니다. 그리고 MapReduce의 의미에서 이는 단순한 기능적 감소와는 약간 다른 작동으로, 다른 기계가 통신하는 방식에 영향을 미칩니다.
Rails가 설치되어있는 경우 (비교를 위해) (실제로는 ActiveSupport 만) :
require 'activesupport'
array.sum
activesupport
A는 대규모 로 이동하는 프로젝트에 드래그에 의존 array.inject(:+)
하는가 array.sum
.
require 'active_support/core_ext/enumerable'
을합니다. .rb
접미사 가 없어야합니다 . 암시 적으로 추가되기 때문입니다.
Ruby> = 2.4.0의 경우 sum
Enumerables에서 사용할 수 있습니다 .
[1, 2, 3, 4].sum
기본 클래스를 mokeypatch하는 것은 위험합니다. 위험을 좋아하고 이전 버전의 Ruby를 사용하는 #sum
경우 Array
클래스에 추가 할 수 있습니다 .
class Array
def sum
inject(0) { |sum, x| sum + x }
end
end
적절하게 이름이 지정된 method를 사용할 수 있습니다 Enumerable#sum
. 그것은 많은 장점이 있습니다inject(:+)
있지만 마지막에 읽을 중요한 메모가 있습니다.
(1..100).sum
#=> 5050
[1, 2, 4, 9, 2, 3].sum
#=> 21
[1.9, 6.3, 20.3, 49.2].sum
#=> 77.7
이 방법은와 동일하지 않습니다 #inject(:+)
. 예를 들어
%w(a b c).inject(:+)
#=> "abc"
%w(a b c).sum
#=> TypeError: String can't be coerced into Integer
또한,
(1..1000000000).sum
#=> 500000000500000000 (execution time: less than 1s)
(1..1000000000).inject(:+)
#=> 500000000500000000 (execution time: upwards of a minute)
다양성을 위해 배열이 숫자 배열이 아니라 숫자 (예 : 양) 속성을 가진 객체 배열 인 경우 에도이 작업을 수행 할 수 있습니다.
array.inject(0){|sum,x| sum + x.amount}
array.map(&:amount).inject(0, :+)
. 다른 답변을 참조하십시오.
map
그런 다음 사용 inject
하려면 배열을 두 번 반복해야합니다. 한 번은 새 배열을 작성하고 한 번은 멤버를 합산합니다. 이 방법은 약간 더 장황하지만 더 효율적입니다.
루비 1.8.7 방법은 다음과 같습니다.
array.inject(0, &:+)
간단하게 사용할 수 있습니다 :
example = [1,2,3]
example.inject(:+)
inject(:+)
가 inject :+
있습니까?
Ruby 2.4.0이 릴리스되었으며 Enumerable # sum 메소드가 있습니다. 그래서 당신은 할 수 있습니다
array.sum
문서의 예 :
{ 1 => 10, 2 => 20 }.sum {|k, v| k * v } #=> 50
(1..10).sum #=> 55
(1..10).sum {|v| v * 2 } #=> 110
또한 다음을 허용합니다 [1,2].sum{|x| x * 2 } == 6
.
# http://madeofcode.com/posts/74-ruby-core-extension-array-sum
class Array
def sum(method = nil, &block)
if block_given?
raise ArgumentError, "You cannot pass a block and a method!" if method
inject(0) { |sum, i| sum + yield(i) }
elsif method
inject(0) { |sum, i| sum + i.send(method) }
else
inject(0) { |sum, i| sum + i }
end
end
end
값이 0이 아닌 배열의 경우 압축을 수행 한 다음 합계를 주입 할 수 있습니다
a = [1,2,3,4,5,12,23.45,nil,23,nil]
puts a.compact.inject(:+)
방법 1 :
[1] pry(main)> [1,2,3,4].sum
=> 10
[2] pry(main)> [].sum
=> 0
[3] pry(main)> [1,2,3,5,nil].sum
TypeError: nil can't be coerced into Integer
방법 2 :
[24] pry(main)> [].inject(:+)
=> nil
[25] pry(main)> [].inject(0, :+)
=> 0
[4] pry(main)> [1,2,3,4,5].inject(0, :+)
=> 15
[5] pry(main)> [1,2,3,4,nil].inject(0, :+)
TypeError: nil can't be coerced into Integer
from (pry):5:in `+'
방법 3 :
[6] pry(main)> [1,2,3].reduce(:+)
=> 6
[9] pry(main)> [].reduce(:+)
=> nil
[7] pry(main)> [1,2,nil].reduce(:+)
TypeError: nil can't be coerced into Integer
from (pry):7:in `+'
방법 4 : Array에 nil 및 empty 값이 포함 된 경우 위의 함수를 사용하면 기본적으로 reduce, sum,
TypeError : nil을 정수로 강제 변환 할 수 없습니다
이것을 극복하면
[16] pry(main)> sum = 0
=> 0
[17] pry(main)> [1,2,3,4,nil, ''].each{|a| sum+= a.to_i }
=> [1, 2, 3, 4, nil, ""]
[18] pry(main)> sum
=> 10
방법 6 : 평가
문자열에서 Ruby 표현식을 평가합니다.
[26] pry(main)> a = [1,3,4,5]
=> [1, 3, 4, 5]
[27] pry(main)> eval a.join '+'
=> 13
[30] pry(main)> a = [1,3,4,5, nil]
=> [1, 3, 4, 5, nil]
[31] pry(main)> eval a.join '+'
SyntaxError: (eval):1: syntax error, unexpected end-of-input
1+3+4+5+
쉬운 방법으로도 할 수 있습니다
def sum(numbers)
return 0 if numbers.length < 1
result = 0
numbers.each { |num| result += num }
result
end
.map 및 .sum을 다음 과 같이 사용할 수 있습니다 .
array.map { |e| e }.sum
array.sum
array.sum