I failed to find anything relevant when I was researching it. I am bascially trying to convert an array, for example [5, 1, 7 ,8] to a fixnum which will have the value of 5178.
3 Answers
[5, 1, 7 ,8].inject{|n, d| n * 10 + d}
# => 5178
Comparison
t = Time.now
100000.times do
[5, 1, 7 ,8].inject{|n, d| n * 10 + d}
end
Time.now - t # => 0.108719628
t = Time.now
100000.times do
[5, 1, 7, 8].join.to_i
end
Time.now - t # => 0.246565502
4 Comments
sawa
Because it does not generate intermediate strings. It does calculation directly within numerals. In my view, it is much more straightforward to calculate decimal digits following its definition rather than converting the digits once to a string and then parsing it as a number.
Alok Anand
@sawa one small modification I would like to suggest for using .inject(0), it increases readability for starting result value. [5, 1, 7 ,8].inject(0){|n, d| n * 10 + d}
Alok Anand
@sawa we can use benchmark too to compare, you might be knowing it for sure, even though have a look kindly here please require 'benchmark' arr = [5,1,7,8] Benchmark.bm do |x| x.report { arr.join.to_i } x.report { arr.inject(0){|result, ele_val| result * 10 + ele_val} } end user system total real 0.000000 0.000000 0.000000 ( 0.000015) 0.000000 0.000000 0.000000 ( 0.000009)
Cary Swoveland
I've upvoted even though there is a comma out of place in the first line.
Do as below:
=> [5, 1, 7 ,8].join.to_f
=> # 5178.0
This too work:
=> [1,2,3,4].join.to_i
=> # 1234
1 Comment
Stanimirovv
Oh I see. I tried using to_i however I got no method error.
arr = [5, 1, 7 ,8]
arr.join.to_i
1 Comment
Alok Anand
1.9.2-p320 :011 > arr = [5, 1, 7 ,8] => [5, 1, 7, 8] 1.9.2-p320 :012 > arr.join.to_i => 5178