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

W

Walle Wallen

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
 
B

Brian Candler

Walle said:
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 ...
 
W

Walle Wallen

Brian said:
Walle said:
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"
 
J

Jesús Gabriel y Galán

Brian said:
Walle said:
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:

=A0 =A0parameters[1..-1].inject ...

Thanks, it worked.

I did a small test in IRB, and it seems like my method should work.
Strange.
a =3D ["a", "b", "c"]
=3D> ["a", "b", "c"]
(a[1]..a[-1]).inject {|result, element| entry + result}
=3D> "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 =3D ["a", "d", "f"]
=3D> ["a", "d", "f"]
irb(main):014:0> (array[1]..array[-1]).inject {|result, element|
result + element}
=3D> "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.
 
J

Josh Cheek

[Note: parts of this message were removed to make it a legal post.]

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
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 ;P )
 
R

Rick DeNatale

2010/3/29 Jes=FAs Gabriel y Gal=E1n said:
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.



--=20
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top