walle
March 29, 2010, 12:26pm
1
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
March 29, 2010, 12:29pm
2
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 …
walle
March 29, 2010, 12:39pm
3
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”
walle
March 29, 2010, 12:58pm
4
Thanks Jesus, I get it now.
walle
March 29, 2010, 12:53pm
5
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.
walle
March 29, 2010, 4:15pm
6
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 )
walle
March 29, 2010, 9:28pm
7
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