1

I have a ruby problem

Here's what i'm trying to do

def iterate1               #define method in given class
 @var3 = @var2.split(" ")  #split string to array
 @var4 = @var3

 @var4.each do |i|         #for each array item do i
   ra = []
   i.each_char {|d|  ra << counter1(d)}  # for each char in i, apply def counter1

   @sum = ra.inject(:+)                  

   @sum2 = @sum.inject(:+)               #have to do the inject twice to get values

 end

@sum2

I know i have over complicated this

Basically the input is a string of letters and values like "14556 this word 398"

I am trying to sum the numbers in each value, seperated by the whitespace like (" ")

When i use the def iterate1 method the block calls the counter1 method just fine, but i can only get the value for the last word or value in the string.

In this case that's 398, which when summed would be 27.

If i include a break i get the first value, which would be 21.

I'm looking to output an array with all of the summed values

Any help would be greatly appreciated

1
  • I'd recommend converting all these ivars to local vars and renaming them properly first. Commented Jul 23, 2012 at 13:20

2 Answers 2

2

I think you're after:

"10 d 20 c".scan(/\b\d+\b/).map(&:to_i).inject(:+) # Returns 30

scan(/\b\d+\b/) will extract all numbers that are made up of digits only in an array, map(&:to_i) will convert them to integers and I guess you already know what inject(:+) will do.

I'm not sure if I understand what you're after correctly, though, so it might help if you provide the answer you expect to this input.

EDIT:

If you want to sum the digits in each number, you can do it with:

"12 d 34 c".scan(/\b\d+\b/).map { |x| x.chars.map(&:to_i).inject(:+) }

x.chars will return an enumerator for the digits, map(&:to_i) will convert them to integers and inject(:+) will sum them.

Sign up to request clarification or add additional context in comments.

4 Comments

im actually looking for each value to be a separate array item, like [27, 21] etc
where would i put the call to my counter1 method. i need to run that method on each value
I don't think I understand your issue :) . If you need to call this on every string containing digits, you can just put a piece of the code I posted in a method and pass the string as an argument. Can you please elaborate? :)
Right Okay. I'm going to go another direction with it after getting advice from a friend. thanks anyway.
0

The simplest answer is to use map instead of each because the former collects the results and returns an array. e.g:

def iterate1               #define method in given class
 @var3 = @var2.split(" ")  #split string to array
 @var4 = @var3

 @var4.map do |i|         #for each array item do i
   ra = []
   i.each_char {|d|  ra << counter1(d)}  # for each char in i, apply def counter1

   @sum = ra.inject(:+)                  
   @sum2 = @sum.inject(:+)               #have to do the inject twice to get values
 end
end

You could write it a lot cleaner though and I think Stefan was a big help. You could solve the issue with a little modification of his code

# when you call iterate, you should pass in the value
# even if you have an instance variable available (e.g. @var2)
def iterate(thing)
  thing.scan(/\b\d+\b/).map do |x| 
    x.chars.map{|d| counter1(d)}.inject(:+)
  end
end

The above assumes that the counter1 method returns back the value as an integer

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.