রুবিতে সংখ্যার অ্যারের যোগফল কিভাবে?


563

আমি পূর্ণসংখ্যার একটি অ্যারে আছে।

উদাহরণ স্বরূপ:

array = [123,321,12389]

এর যোগফল পাওয়ার কোনও ভাল উপায় আছে কি?

আমি জানি, যে

sum = 0
array.each { |a| sum+=a }

কাজ করবে


19
দয়া করে মনে রাখবেন রুবি 2.4+ আছেarray.sum
Dawg

রুবি 2.6 এর এটি নেই। রুবি দেয়, রুবি সরিয়ে নেয়, মনে হয়।
লোরি


দুঃখিত। সেই সময় আমি ভুল করে বিশ্বাস করেছিলাম যে আমার পক্ষ থেকে একটি রেবেনভ স্লিপ-আপ হওয়ার কারণে আমি ২.6 ব্যবহার করছি।
লরি

উত্তর:


612

এটা চেষ্টা কর:

array.inject(0){|sum,x| sum + x }

রুবির আনুমানিক ডকুমেন্টেশন দেখুন

(দ্রষ্টব্য: 0বেস কেসটি প্রয়োজন তাই 0এটির পরিবর্তে খালি অ্যারেটিতে ফিরে আসবে nil)


317
জর্নি এর array.inject(:+)আরও দক্ষ।
পিটার

3
array.inject(:+)রুবিতে সমস্যা দেখা দিয়েছে বলে মনে হচ্ছে ১.৮..6 ব্যতিক্রমগুলি "লোকালজম্প ইরার: কোনও ব্লক দেওয়া হয়নি" পপ আপ হতে পারে।
কামিল জাজোট

34
রেলগুলিতে array.sumআপনাকে অ্যারের মানগুলির যোগফল দিতে পারে।
কামিল জাজট

32
বেশিরভাগ ক্ষেত্রে, আমি ব্যবহার করতে পছন্দ করি reduce, যা inject(যেমন হিসাবে array.reduce( :+ )) এর একটি উপনাম ।
বরিস স্ট্যাটনিকি

3
@ বোরিস এছাড়াও, রুবাইকপ injectপরিবর্তে ব্যবহারের জন্য আপনাকে সতর্ক করবে reduce
ড্রুগানস

810

অথবা রুবি ১.৯ উপায় চেষ্টা করুন:

array.inject(0, :+)

দ্রষ্টব্য: 0বেস কেসটি প্রয়োজনীয় অন্যথায় nilখালি অ্যারেতে ফিরে আসবে:

> [].inject(:+)
nil
> [].inject(0, :+)
0

6
কীভাবে আমি অবজেক্ট থেকে কোনও গুণকে যোগ করতে এইভাবে ব্যবহার করতে পারি। আমার অ্যারে [product1, product2] আমি product1.price + product2.price যোগ করতে চাই। অ্যারে ইন্ডিজেক্ট (: +) ব্যবহার করা কি সম্ভব?
পাবলো ক্যানটারো

7
আপনি মানচিত্রের পদ্ধতিতে অনুরূপ কৌশল ব্যবহার করতে পারেন: অ্যারে.ম্যাপ (& দাম) .আইনজেক্ট (: +)
মার্কেজজাদা

100
array.map(&:price).inject(0, :+)কিছুটা নিরাপদ। এটি নিশ্চিত করে যে আপনার যদি খালি তালিকা থাকে তবে শূন্যের পরিবর্তে 0 পাবেন ।
জন

11
অ্যারে.ম্যাপ (...) ব্যবহার করে ইনজেকশন (...) অক্ষম, আপনি সমস্ত ডেটা দু'বার পুনরাবৃত্তি করবেন। চেষ্টা করুন array.inject(0) { |sum, product| sum += product.price }
everett1992

4
@ everett1992 এবং এটি হিসাবে দেখা যাচ্ছে, এমনকি একটি অপ্টিমাইজেশনও নয়। এটি দুটি পর্যায়ে করা আমার জন্য ধারাবাহিকভাবে দ্রুত। gist.github.com/cameron-martin/b907ec43a9d8b9303bdc
ক্যামেরন মার্টিন

290
array.reduce(0, :+)

এর সমতুল্য হলেও array.inject(0, :+), শব্দটি হ্রাস ম্যাপ্রেডিউস প্রোগ্রামিং মডেলগুলির উত্থানের সাথে আরও সাধারণ ভাষায় প্রবেশ করছে ।

ইনজেকশন , হ্রাস , ভাঁজ , জমা এবং সংকোচনের বিষয়গুলি ভাঁজ ফাংশনগুলির এক শ্রেণির সমার্থক । আমি আপনার কোড বেস জুড়ে ধারাবাহিকতা সবচেয়ে গুরুত্বপূর্ণ, কিন্তু বিভিন্ন সম্প্রদায় যেহেতু একটি শব্দ অন্য শব্দকে পছন্দ করে তাই বিকল্পগুলি জানার পক্ষে এটি দরকারী।

মানচিত্র-হ্রাস শব্দটির উপর জোর দেওয়ার জন্য, এখানে এমন একটি সংস্করণ রয়েছে যা সেই অ্যারেতে কী শেষ হয় তার থেকে একটু বেশি ক্ষমাযোগ্য।

array.map(&:to_i).reduce(0, :+)

কিছু অতিরিক্ত প্রাসঙ্গিক পড়া:


11
আমি সম্মত, reduceফাংশনটি কী করে তা আমাকে আরও জানান, তবে injectএটি আরও শীতল শোনায়।
everett1992

1
সর্বশেষ মন্তব্যের সাথে একমত, আপনি আমাকে সেরা উত্তর দিয়েছেন।
জার্সকা

1
এক মন্তব্য আমি করতে হবে যে reduceএবং mapযেমন উচ্চতর-অর্ডার ফাংশন predate MapReduce। অনুপ্রেরণা অন্যভাবে চালায়। এবং ম্যাপ্রেডস অর্থে এটি কোনও সাধারণ ক্রিয়াকলাপ হ্রাসের চেয়ে কিছুটা আলাদা অপারেশন, এতে বিভিন্ন মেশিন কীভাবে যোগাযোগ করে তার জড়িত থাকে।
আকজয়

কেন আইভারসন অপারেটরটিকে পরিচয় করিয়েছিলেন / প্রোগ্রামিং ল্যাঙ্গুয়েজ এপিএলে "হ্রাস অপারেটর" বলেছিলেন। সূত্র: আইভারসন, কেনেথ। 1962. একটি প্রোগ্রামিং ভাষা। উইলি। অন্য উত্স: "চিন্তার সরঞ্জাম হিসাবে চিহ্নিতকরণ
ফার্নান্দো

112

বিকল্পভাবে (কেবল তুলনার জন্য), আপনি যদি রেলগুলি ইনস্টল করেন (আসলে কেবল অ্যাক্টিভসপোর্ট):

require 'activesupport'
array.sum

12
সক্রিয় সমর্থনগুলির নতুন সংস্করণগুলি ডিফল্টরূপে সমস্ত এক্সটেনশন লোড করে না। উভয় শুধু সমষ্টি মডিউল প্রয়োজন আপনি চাইবেন: require 'active_support/core_ext/enumerable.rb'বা সক্রিয় সমর্থনের প্রয়োজন: require 'active_support/all'। এটি সম্পর্কে এখানে আরও: এপিআই ডক্স
ডিসক্যাশম্যান

2
কিছু মনে করবেন না যে activesupportএকটি হল বৃহদায়তন থেকে যেতে একটি প্রকল্পে টেনে আনার নির্ভরতা array.inject(:+)থেকে array.sum
মেগার

1
নিতপিক অন্যথায় ভাল মন্তব্যে: এটি প্রত্যয় require 'active_support/core_ext/enumerable'ছাড়াই হওয়া উচিত .rb, কারণ এটি স্পষ্টভাবে যুক্ত করা হয়েছে।
প্রতি লন্ডবার্গ

72

রুবি> = ২.৪.০ এর জন্য আপনি sumঅঙ্কের থেকে ব্যবহার করতে পারেন ।

[1, 2, 3, 4].sum

এটি বেস ক্লাসগুলি মোকিপ্যাচ করা বিপজ্জনক। আপনি যদি বিপদটি পছন্দ করেন এবং রুবির কোনও পুরানো সংস্করণ ব্যবহার করছেন তবে #sumআপনি Arrayক্লাসে যুক্ত করতে পারেন :

class Array
  def sum
    inject(0) { |sum, x| sum + x }
  end
end

1
দয়া করে এটি করবেন না
ব্যবহারকারী 3467349

@ ব্যবহারকারী 3467349 কেন?
YoTengoUnLCD

15
বেস ক্লাসগুলি মনকিপাচিং ভাল নয়।
ব্যবহারকারী 3467349

1
তিনি যে বক্তব্যটি দিচ্ছেন তা হ'ল রুবি> = 2.4 এর জন্য আপনার বানর প্যাচ করার দরকার নেই, এবং সেই বানর প্যাচিং বিপজ্জনক, এবং এখন আপনি দেশীয়ভাবে অঙ্কের পরিমাণ যোগ করতে পারেন, তবে কার্যকারিতা ব্যাকপোর্ট করার একটি উপায়ও রয়েছে।
পিটার এইচ। বলিং

ডাউনভোটেড কারণ আপনার প্রয়োগটি খালি অ্যারেতে শূন্য করে।
এল্ড্রিচ কনড্রাম

45

রুবি ২.৪.০ এর জন্য নতুন

আপনি উপযুক্ত নামকরণ পদ্ধতিটি ব্যবহার করতে পারেন 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)

কেন এই রকম হয় তার আরও তথ্যের জন্য এই উত্তরটি দেখুন sum


19

কেবলমাত্র বৈচিত্র্যের স্বার্থে, আপনি এটি করতে পারেন যদি আপনার অ্যারে সংখ্যার অ্যারে না হয়ে থাকে তবে বরং বস্তুর একটি অ্যারে যাতে সংখ্যার বৈশিষ্ট্য রয়েছে (যেমন পরিমাণ):

array.inject(0){|sum,x| sum + x.amount}

3
এই কাজ সমতূল্য: array.map(&:amount).inject(0, :+)। অন্যান্য উত্তর দেখুন।
রিচার্ড জোন্স

4
একরকম, হ্যাঁ তবে mapএরপরে ব্যবহারের injectজন্য আপনাকে অ্যারের মধ্য দিয়ে দু'বার লুপ করতে হবে: একবার নতুন অ্যারে তৈরি করার জন্য, অন্যটি সদস্যদের যোগফল যোগ করতে হবে। এই পদ্ধতিটি সামান্য আরও ভার্বোজ, তবে আরও কার্যকর।
হ্যাশফেইল

দৃশ্যত এটি আরও দক্ষ নয়, দেখতে gist.github.com/cameron-martin/b907ec43a9d8b9303bdc : এই উত্তরে মন্তব্য ক্রেডিট - stackoverflow.com/a/1538949/1028679
rmcsharry

19

রুবি ২.৪++ / রেল - array.sumযেমন[1, 2, 3].sum # => 6

রুবি প্রাক 2.4 - array.inject(:+)বাarray.reduce(:+)

* দ্রষ্টব্য: #sumপদ্ধতিটি ২.৪-এর একটি নতুন সংযোজন, enumerableসুতরাং আপনি এখন array.sumকেবল রেলগুলিই নয়, খাঁটি রুবিতে ব্যবহার করতে সক্ষম হবেন ।


2
রুবি ২.৪.০ প্রকাশিত হয়েছিল এই বৈশিষ্ট্যটির সাথে! 🎉
অ্যামিবে

@ ঠিক আছে আপনি ঠিক! এই দরকারী বৈশিষ্ট্য অন্তর্ভুক্ত দেখে খুশি।
সংগ্রহ করুন

18

রুবি 1.8.7 উপায় নিম্নলিখিত:

array.inject(0, &:+) 

আপনি যদি আমার ২০১১ এর মন্তব্যটি পড়ে থাকেন এবং আপনি এখনও 1.8.6 ব্যবহার করছেন তবে এটি প্রাসঙ্গিক, দয়া করে আপগ্রেড করুন!
অ্যান্ড্রু গ্রিম

16

আপনি কেবল ব্যবহার করতে পারেন:

    example = [1,2,3]
    example.inject(:+)

কেন এটি কাজ করে: inject(:+)তবে এটি কাজ করে না inject :+?
আর্নল্ড রোয়া

@ আর্নল্ডরোয়া "ইনজেকশন: +" এটি আমার জন্য কাজ করে, আপনি কী ফলাফল পেয়েছেন?
গণেশ সাগরে


5

রুবি ২.৪.০ প্রকাশিত হয়েছে এবং এটির একটি পরিসংখ্যক # যোগ পদ্ধতি রয়েছে। সুতরাং আপনি করতে পারেন

array.sum

দস্তাবেজগুলির উদাহরণ:

{ 1 => 10, 2 => 20 }.sum {|k, v| k * v }  #=> 50
(1..10).sum                               #=> 55
(1..10).sum {|v| v * 2 }                  #=> 110

3

এছাড়াও এর জন্য অনুমতি দেয় [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

3

শূন্য মান সহ অ্যারের জন্য আমরা কমপ্যাক্ট করতে পারি এবং তারপরে যোগফলটি ইনজেক্ট করতে পারি-

a = [1,2,3,4,5,12,23.45,nil,23,nil]
puts a.compact.inject(:+)

2
array.reduce(:+)

জন্য কাজ করে রেঞ্জ খুব ... তাই

(1..10).reduce(:+) returns 55

1

যদি আপনি গোল্ফ লাগেন তবে আপনি এটি করতে পারেন

eval([123,321,12389]*?+)

এটি "123 + 321 + 12389" একটি স্ট্রিং তৈরি করবে এবং তারপরে যোগফলটি করতে ফাংশন ইভাল ব্যবহার করবে। এটি কেবল গল্ফিংয়ের উদ্দেশ্যে , আপনার এটি সঠিক কোডে ব্যবহার করা উচিত নয়।


1

পদ্ধতি 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: অ্যারেতে যখন শূন্য এবং ফাঁকা মান থাকে, আপনি যদি পূর্বের কোনও ফাংশন হ্রাস করেন, যোগ করেন তবে ইনজেকশনের মাধ্যমে

TypeError: পূর্ণসংখ্যার সাথে জোর করা যায় না

আপনি এটি দ্বারা কাটিয়ে উঠতে পারেন,

   [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+

1

3 টি উপায়ে আমরা অ্যারের যোগফল করতে পারি

1) array.inject(0){|sum,x| sum + x }

2) array.inject('+')

3) array.join('+')


0

অথবা আপনি এই পদ্ধতিটি ব্যবহার করে দেখতে পারেন:

def sum arr
  0 if arr.empty
  arr.inject :+
end


0
number = [1..100]

number. each do |n|

    final_number = n.sum

    puts "The sum is #{final_number}"
end

* এটি একজন নতুন বিকাশকারী হিসাবে আমার পক্ষে ভাল কাজ করেছে। [] এর মধ্যে মানগুলি পরিবর্তন করে আপনি আপনার নম্বর পরিসরটি সামঞ্জস্য করতে পারেন



-8

আপনি .map এবং .sum এর মতো ব্যবহার করতে পারেন :

array.map { |e| e }.sum

3
একটি মানচিত্র একই উপাদান ফিরে আসার কী? এটি ঠিক একইরকমarray.sum
আর্নল্ড রোয়া

তাছাড়া অ্যারে.সাম রুবিতে নেই doesn't দেখুন মাইক Woodhouse উত্তর
উলিসে বিএন

এটি এখন রুবি ২.৪.০-এ রয়েছে
ইনস্টলারটি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.