Reputation: 1
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
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
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