Easy task, Sum array element... Why doesn't it work?

I have done it many times before, but this time I can’t get it too work.
I’m starting to get a bit frustrating.
So, I’m trying to sum all elements from the second element in a Array
using inject. The problem is that inject returns nil every time. What am
I doing wrong?

parameters.each {|element| print element + “,”} --> ?faq,using,rtorrent
parameters.each {|element| print element.class.to_s + “,”} -->
String,String,String
parameters.class --> Array

Doesn’t work.
(parameters[1]…parameters[-1]).inject {|result, element| result +
element} --> nil
Neither does.
(parameters[1]…parameters[-1]).to_a.inject {|result, element| result +
element} --> nil

//Walle

Walle W. wrote:

Doesn’t work.
(parameters[1]…parameters[-1]).inject {|result, element| result +

That’s creating a new Range object: (“faq”…“rtorrent”)

What you want is an array slice:

parameters[1…-1].inject …

Brian C. wrote:

Walle W. wrote:

Doesn’t work.
(parameters[1]…parameters[-1]).inject {|result, element| result +

That’s creating a new Range object: (“faq”…“rtorrent”)

What you want is an array slice:

parameters[1…-1].inject …

Thanks, it worked.

I did a small test in IRB, and it seems like my method should work.
Strange.
a = [“a”, “b”, “c”]
=> [“a”, “b”, “c”]

(a[1]…a[-1]).inject {|result, element| entry + result}
=> “bc”

Thanks Jesus, I get it now.

On Mon, Mar 29, 2010 at 12:39 PM, Walle W. [email protected]
wrote:

Thanks, it worked.

I did a small test in IRB, and it seems like my method should work.
Strange.
a = [“a”, “b”, “c”]
=> [“a”, “b”, “c”]

(a[1]…a[-1]).inject {|result, element| entry + result}
=> “bc”

As Brian has explained, (a[1]…[a-1]) creates a range. When you
iterate a range, it calls succ starting on the first element until it
reaches the last one. In your example with a, b, c:

irb(main):006:0> (“a”…“c”).each {|s| p s}
“a”
“b”
“c”

You get the three elements of the array, by chance. Try changing that
to something else, for example:

irb(main):013:0> array = [“a”, “d”, “f”]
=> [“a”, “d”, “f”]
irb(main):014:0> (array[1]…array[-1]).inject {|result, element|
result + element}
=> “def”

In your original example, the words were quite far apart:

irb(main):005:0> (“faq”…“rtorrent”).each_with_index {|s, i| p s;
break if i > 20}
“faq”
“far”
“fas”
“fat”
“fau”
“fav”
“faw”
“fax”
“fay”
“faz”
“fba”
“fbb”
“fbc”
“fbd”
“fbe”
“fbf”
“fbg”
“fbh”
“fbi”
“fbj”
“fbk”
“fbl”

and so on until “rtorrent”.

Jesus.

On Mon, Mar 29, 2010 at 4:26 AM, Walle W. [email protected]
wrote:

Rails has this by default:
http://api.rubyonrails.org/classes/Enumerable.html#M002571

module Enumerable
def sum(identity = 0, &block)
return identity unless size > 0

if block_given?
  map(&block).sum
else
  inject { |sum, element| sum + element }
end

end
end

[‘a’,‘b’,‘c’].sum # => “abc”
[1,2,3].sum # => 6
[[0],[‘0’],[:‘0’],[/0/]].sum # => [0, “0”, :“0”, /0/]
[].sum(/abc/) # => /abc/
[1,2,3].sum(/abc/) # => 6
[‘a’,‘b’,‘c’].sum(&:upcase) # => “ABC”

That last one is 1.9 only (or another monkey patch :stuck_out_tongue_winking_eye: )

2010/3/29 Jesús Gabriel y Galán [email protected]:

On Mon, Mar 29, 2010 at 12:39 PM, Walle W. [email protected] wrote:

In your original example, the words were quite far apart:

irb(main):005:0> (“faq”…“rtorrent”).each_with_index {|s, i| p s;
break if i > 20}

Actually in his original example parameters appears to be [“?faq” ,
“using” , “rtorrent”]

so

(parameters[1]…parameters[-1])

is

(“using”…“rtorrent”)

and since “using” > “rtorrent” the range is empty which is why inject
returns nil.


Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale