ฉันมีอาร์เรย์ของจำนวนเต็ม
ตัวอย่างเช่น:
array = [123,321,12389]มีวิธีที่ดีที่จะได้รับผลรวมของพวกเขา?
ฉันรู้แล้ว
sum = 0
array.each { |a| sum+=a }จะทำงาน.
ฉันมีอาร์เรย์ของจำนวนเต็ม
ตัวอย่างเช่น:
array = [123,321,12389]มีวิธีที่ดีที่จะได้รับผลรวมของพวกเขา?
ฉันรู้แล้ว
sum = 0
array.each { |a| sum+=a }จะทำงาน.
คำตอบ:
ลองสิ่งนี้:
array.inject(0){|sum,x| sum + x }(หมายเหตุ: 0จำเป็นต้องใช้ตัวพิมพ์ใหญ่เพื่อ0ส่งคืนอาร์เรย์ว่างเปล่าแทนnil)
array.inject(:+)มีประสิทธิภาพมากขึ้น
                    array.inject(:+)ดูเหมือนว่าจะทำให้เกิดปัญหาใน Ruby 1.8.6 ข้อยกเว้น "LocalJumpError: ไม่มีบล็อกที่กำหนด" อาจปรากฏขึ้น
                    array.sumอาจให้ผลรวมของค่าอาร์เรย์
                    reduceซึ่งเป็นนามแฝงของinject(เหมือนในarray.reduce( :+ ))
                    inject reduce
                    หรือลองใช้วิธี Ruby 1.9:
array.inject(0, :+)หมายเหตุ: 0กรณีฐานเป็นสิ่งจำเป็นมิฉะนั้นnilจะถูกส่งกลับในอาร์เรย์ที่ว่างเปล่า:
> [].inject(:+)
nil
> [].inject(0, :+)
0array.map(&:price).inject(0, :+)ปลอดภัยกว่านิดหน่อย มันทำให้แน่ใจว่าถ้าคุณมีรายการที่ว่างเปล่าที่คุณได้รับ0แทนศูนย์ 
                    array.inject(0) { |sum, product| sum += product.price }
                    array.reduce(0, :+)ในขณะที่เทียบเท่ากับarray.inject(0, :+)คำว่าลดกำลังเข้าสู่พื้นถิ่นที่พบบ่อยมากขึ้นด้วยการเพิ่มขึ้นของการเขียนโปรแกรม MapReduce รุ่น
ฉีด , ลด , พับ , สะสมและการบีบอัดที่มีความหมายเหมือนกันทั้งหมดเป็นชั้นของฟังก์ชั่นพับฟังก์ชั่นพับฉันพบว่าความสม่ำเสมอของรหัสฐานของคุณสำคัญที่สุด แต่เนื่องจากชุมชนต่าง ๆ มักจะชอบมากกว่าคำเดียวมันจึงมีประโยชน์ที่จะรู้ทางเลือกอื่น
เพื่อเน้นแผนที่ลดการใช้คำฟุ่มเฟือยนี่เป็นรุ่นที่ให้อภัยสิ่งที่เกิดขึ้นในอาเรย์นั้นเล็กน้อย
array.map(&:to_i).reduce(0, :+)การอ่านที่เกี่ยวข้องเพิ่มเติมบางส่วน:
reduceบอกฉันมากกว่าสิ่งที่ฟังก์ชั่นทำ แต่injectเสียงเย็นกว่ามาก
                    reduceและmapฟังก์ชั่นที่สูงกว่าการสั่งซื้อก่อนวันจริง MapReduce แรงบันดาลใจวิ่งไปทางอื่น และในแง่ของ MapReduce มันเป็นการดำเนินการที่แตกต่างจากการลดฟังก์ชันการทำงานอย่างง่ายโดยมีความหมายว่าเครื่องต่างกันอย่างไร
                    อีกทางเลือกหนึ่ง (สำหรับการเปรียบเทียบเท่านั้น) หากคุณติดตั้ง Rails (จริงๆแล้วเป็นแค่ ActiveSupport):
require 'activesupport'
array.sumrequire 'active_support/core_ext/enumerable.rb' require 'active_support/all'เพิ่มเติมเกี่ยวกับที่นี่: เอกสาร API
                    activesupportเป็นขนาดใหญ่พึ่งพาลากเข้าไปในโครงการที่จะไปจากการ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
endEnumerable#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)ดูคำตอบนี้สำหรับข้อมูลเพิ่มเติมเกี่ยวกับสาเหตุที่sumเป็นเช่นนี้
เพื่อความหลากหลายคุณสามารถทำได้ถ้าอาร์เรย์ของคุณไม่ใช่อาร์เรย์ของตัวเลข แต่เป็นอาร์เรย์ของวัตถุที่มีคุณสมบัติที่เป็นตัวเลข (เช่นจำนวน):
array.inject(0){|sum,x| sum + x.amount}array.map(&:amount).inject(0, :+). ดูคำตอบอื่น ๆ
                    mapแล้วinjectคุณจะต้องห่วงผ่านอาร์เรย์สองครั้งเพื่อสร้างอาร์เรย์ใหม่อื่น ๆ ที่จะสรุปสมาชิก วิธีนี้ค่อนข้างละเอียดกว่าเล็กน้อย แต่ก็มีประสิทธิภาพมากกว่าด้วย
                    Ruby 2.4+ / Rails - array.sumเช่น[1, 2, 3].sum # => 6
ทับทิมก่อน 2.4 - array.inject(:+)หรือarray.reduce(:+)
* หมายเหตุ: #sumวิธีนี้เป็นส่วนเสริมใหม่สำหรับ 2.4 enumerableดังนั้นตอนนี้คุณจะสามารถใช้array.sumในทับทิมบริสุทธิ์ไม่ใช่แค่ Rails
ruby 1.8.7 way เป็นดังต่อไปนี้:
array.inject(0, &:+) คุณสามารถใช้:
    example = [1,2,3]
    example.inject(:+)inject(:+)แต่นี้ไม่ได้inject :+?
                    นี่เพียงพอแล้ว
       [1,2,3].inject('+')
ทับทิม 2.4.0 ถูกปล่อยออกมาและมันก็มี# รวม Enumerableวิธี ดังนั้นคุณสามารถทำได้
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สำหรับอาร์เรย์ที่มีค่าศูนย์เราสามารถทำขนาดกะทัดรัดแล้วฉีดผลรวม
a = [1,2,3,4,5,12,23.45,nil,23,nil]
puts a.compact.inject(:+)array.reduce(:+)ใช้งานได้สำหรับช่วงเช่นกัน ...
(1..10).reduce(:+) returns 55ถ้าคุณรู้สึกว่ากอล์ฟคุณสามารถทำได้
eval([123,321,12389]*?+)สิ่งนี้จะสร้างสตริง "123 + 321 + 12389" จากนั้นใช้ฟังก์ชัน eval เพื่อหาผลรวม นี่เป็นเพียงการเล่นกอล์ฟเท่านั้นคุณไม่ควรใช้รหัสนี้อย่างถูกต้อง
วิธีที่ 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 มีค่าศูนย์และค่าว่างโดยค่าเริ่มต้นหากคุณใช้ฟังก์ชันใด ๆ ข้างต้นลด, ผลรวม, ฉีดทุกอย่างจะผ่าน
TypeError: ไม่มีค่าบังคับใน Integer
คุณสามารถเอาชนะสิ่งนี้ได้โดย
   [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: eval
หาค่านิพจน์ทับทิมในสตริง
  [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+3 วิธีที่เราสามารถทำผลรวมของอาร์เรย์
1) array.inject(0){|sum,x| sum + x }
2) array.inject('+')
3) array.join('+')
หรือคุณสามารถลองวิธีนี้:
def sum arr
  0 if arr.empty
  arr.inject :+
endนี่เป็นวิธีที่สั้นที่สุด ลองมัน.
array.inject :+
number = [1..100]
number. each do |n|
    final_number = n.sum
    puts "The sum is #{final_number}"
end* สิ่งนี้ทำงานได้ดีสำหรับฉันในฐานะนักพัฒนาใหม่ คุณสามารถปรับช่วงตัวเลขของคุณโดยการเปลี่ยนค่าภายใน []
คุณสามารถทำได้ง่ายๆ
def sum(numbers)
  return 0 if numbers.length < 1
  result = 0
  numbers.each { |num| result += num }
  result
endคุณสามารถใช้. mapและ. sum ได้เช่น:
array.map { |e| e }.sumarray.sum
                    
array.sum