0

So I want to use instance variables to do something like

@array.each {|x,y|x+y}

It doesn't seem to be working, and I'm wondering if that is the correct syntax to use with an instance variable, or should it be something like

@array.each |x, y| x+y

or

@array.each [|x,y| x+y]

Do I need to use yield for this?

maudulus
  • 10,627
  • 10
  • 78
  • 117
  • 1
    What do you expect to happen? – Sergio Tulentsev Feb 03 '14 at 17:09
  • 2
    In general terms, there's no difference between a local and a instance variable, except for its scope. You can use it the very same way. – lucke84 Feb 03 '14 at 17:12
  • 1
    You most likely meant `inject`: @array.inject(0){|x, y| x + y} yields the sum of all elements in the array. – PinnyM Feb 03 '14 at 17:12
  • It doesn't work...I expect it to at the elements in the array and add the first to the seocond, and so on, until all of the elements are added. – maudulus Feb 03 '14 at 17:12
  • I'll try the inject method - the could be what I was forgetting. Is there a way to do this without inject? – maudulus Feb 03 '14 at 17:13
  • I think you need to provide sample input and output. Your expectation is not clear. – Mark Thomas Feb 03 '14 at 17:14
  • What's wrong with `inject` that motivates you to use another way? You could use `each_with_object` (or `each.with_object`) to do something similar in a more verbose fashion... but to what end? – PinnyM Feb 03 '14 at 17:15
  • 1
    Duplicate of http://stackoverflow.com/questions/1538789/how-to-sum-array-members-in-ruby – Beartech Feb 03 '14 at 17:16
  • what's wrong with `array.inject{|sum,x| sum + x }`? – rony36 Feb 03 '14 at 17:18
  • What about yield? When does that become necessary? – maudulus Feb 03 '14 at 17:20
  • @modulus I believe you're asking too many questions all at once :) BTW you don't need to use `yield`. – lucke84 Feb 03 '14 at 17:24
  • You could have ruled out the two alternatives you mention but just trying them in IRB or Pry. I certainly hope you are using one of those tools. – Cary Swoveland Feb 03 '14 at 18:08

4 Answers4

1

In general terms, there's no difference between a local and a instance variable, except for its scope. You can use it the very same way.

The problem with your code is that there's no each with two variables (x and y, in your example) for arrays.

You can do either:

total = 0
@array.each { |x| total += x }

Or:

total = @array.inject(0) { |tot, x| tot += x }

Or:

total = @array.inject { |tot, x| tot += x }

Which can be written also like this:

total = @array.inject(:+)
lucke84
  • 4,516
  • 3
  • 37
  • 58
  • 1
    You don't actually need to set the initial value for inject. `tot` will automatically be loaded with the first array element, and the block will execute for each remaining array eement. – SteveTurczyn Feb 03 '14 at 17:18
  • You also don't need the `+=` with inject. The result of the block evaluation becomes the next memo value, so `@array.inject {|tot, x| tot + x}` is sufficient. – pjs Feb 03 '14 at 18:42
0

You should have only one variable within the block:

@array.each { |x| ... }

The method each will traverse the array one by one.

Shoe
  • 74,840
  • 36
  • 166
  • 272
  • The inject works, and I can use the syntax you've listed to solve another issue that i have, since it is targetted at working with each instance. – maudulus Feb 03 '14 at 17:18
0

You are looking for inject:

@array.inject(:+)
BroiSatse
  • 44,031
  • 8
  • 61
  • 86
0

If you want to sum the elements (which seems to be your purpose).

@array.inject(:+)
SteveTurczyn
  • 36,057
  • 6
  • 41
  • 53