ebfd
ebfd

Reputation: 1

I want to return the string that has the highest sum in an array for Ruby

So far I am able to return the sums of the strings:

puts "Please enter strings of #'s to find the number that has the greatest sum."
puts "Use commas to separate #'s."
user_input = gets.chomp
array = user_input.split(",")
array.map do |num_string|
  num_string.chars.map(&:to_i).inject(:+)
end

But I wish to return the string that adds up to the highest value. For instance: If I have array = ["123","324","644"] I need it to return the sums of each value so the result should be 6,9,and 14 respectively. Since 1+2+3=6 etc. I am this far but now I need to return "644" as the answer since it is the string that sums to the highest value.

Upvotes: 0

Views: 146

Answers (2)

Leah Zorychta
Leah Zorychta

Reputation: 13409

yourArray = ["123","324","644"]
highest = -1
pos = -1
yourArray.each_with_index{ |str, i| 
  sum = str.split("").map(&:to_i).reduce(:+)
  highest = [highest,sum].max
  pos = i if highest == sum
}
puts "highest value is " + yourArray[pos]

lets look at each step, map lets us enumerate the array and returns a new array with whatever we return from map:

yourArray.map{ |str| ... }

Here we're taking our strings in the array and splitting them into arrays of ["1","2","3"] for example, then the to_i portion converts this to an array such as [1,2,3] then finally reduce gives us our sum:

sum = str.split("").map(&:to_i).reduce(:+)

Here we're keeping track throughout the loop of the highest sum we've seen so far:

highest = [highest,sum].max

If ever the current sum is the highest, store its position in the array

pos = i if highest = sum

finally, use the stored array position to print out whatever exists there in the original array (the positions line up):

puts "highest value is " + yourArray[pos]

Upvotes: 2

Cary Swoveland
Cary Swoveland

Reputation: 110675

I suggest you use Enumerable#max_by:

arr = ["123","324","644"]

arr.max_by { |s| s.each_char.reduce(0) { |t,c| t+c.to_i } }
  #=> "644"

Let's see how this works. Enumerable#max_by computes a value for each element of arr and returns the element of arr whose computed value is greatest. The calculation of the value for each element is done by max_by's block.

enum0 = arr.max_by
  #=> #<Enumerator: ["123", "324", "644"]:max_by> 

You can see the three elements of this enumerator. Sometimes it's not so obvious, but you can always see what they are by converting the enumerator to an array:

enum0.to_a
  #=> ["123", "324", "644"]

Elements of enum0 are passed to the block by the method Enumerator#each (which in turn calls Array#each). You would find that:

enum0.each { |s| s.each_char.reduce(0) { |t,c| t+c.to_i } }

returns "644".

The first element of the enumerator ("123") is passed to the block by each and assigned to the block variable s. We can simulate that with the method Enumerator#next:

s = enum0.next
  #=> "123"

Within the block we have another enumerator:

enum1 = s.each_char
  #=> #<Enumerator: "123":each_char> 
enum1.to_a
  #=> ["1", "2", "3"]
enum1.reduce(0) { |t,c| t+c.to_i }
  #=> 6

This last statement is equivalent to:

0            #  initial value of t
0 + "1".to_i #=> 1 (new value of t)
1 + "2".to_i #=> 3 (new value of t)
3 + "3".to_i #=> 6 (new value of t)

6 is then returned by reduce.

For the next element of enum0:

s = enum0.next
  #=> "324"
s.each_char.reduce(0) { |t,c| t+c.to_i }
  #=> 9

and for the last element enum0:

s = enum0.next
  #=> "644"
s.each_char.reduce(0) { |t,c| t+c.to_i }
  #=> 14

Since 14 is the largest integer in [6, 9, 14], max_by returns the last element of arr, "644".

Upvotes: 3

Related Questions