Simple ruby array smallest integer? - ruby

This is my array : array = ["1", "Hel", "6", "3", "lo" ]I want to output the smallest number in the array. Then I want to output the largest number in the array? How do I achieve this? Thanks!

Well it depends how you want to handle the string elements that aren't easily parsed into numbers. Like "Hel" and "lo".
If you do this:
array.map {|x| Integer(x) rescue nil }.compact.min
array.map {|x| Integer(x) rescue nil }.compact.max
Then you'll ignore those, which is probably the right thing, assuming you don't have some reason for considering "Hel" and "lo" to have numerical values.

numbers = array.select { |x| x[/^-?\d+$/] }.map(&:to_i)
# => [1, 6, 3]
numbers.min
# => 1
numbers.max
# => 6

Another variation to work with negative numbers
smalles, largest =
["1", "Hel", "6", "3", "lo","-9" ].select { |x| x[/^-?\d+$/] }.minmax_by(&:to_i)
smallest # => -9 largest # => 6

smallest, largest =
["1", "Hel", "6", "3", "lo" ].reject{|s| s =~ /\D/}.minmax_by(&:to_i)
smallest # => "1"
largest # => "6"

Another way:
array.join(',').scan(/-?\d+/).minmax_by(&:to_i)
#=> ["-4", "6"]

we can use unicode [[:digit:]] instead writing regular expression as
array.join(',').scan(/[[:digit:]]/).minmax_by(&:to_i)

Related

How to split a long number into pairs of digits

I have a string of a long number 12345678 and want to convert it to an array like this :
["12", "34", "56", "78"].
I have tried array.split(//).map { |e| e.to_i } but it does
["1", "2", "3", "4", "5", "6", "7", "8"]
The simplest way would be to use String#scan with the Regexp /../, which matches any pair of characters:
n = 12345678
arr = n.to_s.scan(/../)
# => ["12", "34", "56", "78"]
If you need to handle odd numbers of digits and keep the last digit, use /..?/ instead:
n = 123456789
arr = n.to_s.scan(/..?/)
# => ["12", "34", "56", "78", "9"]
An alternative approach would be to map over the range 0...n.to_s.size using the Range#step method:
n = 123456789
str = n.to_s
arr = (0...str.size).step(2).map {|i| str[i, 2] }
# => ["12", "34", "56", "78", "9"]
You can see all three approaches in action on repl.it: https://repl.it/#jrunning/BlissfulAcclaimedStrategy
I think there is no need to use a regexp, I would do something like this:
12345678.to_s.chars.each_slice(2).map(&:join)
#=> ["12","34","56","78"]
You can use
p = 123456789.to_s
(0..p.length).each_cons(2).map {|i, j| "#{p[i]}#{p[j]}" if i%2 == 0}.compact

Combinations of consecutive elements of an array

Is there any builtin method to produce combinations of consecutive array elements?
a = ['1','2','3','4']
# => '12','23','34'
I tried the methods permutation, combination, and each_slice, but was not able to produce required output.
a.permutation(2).to_a #=> [[1,2],[1,3],[1,4],[2,1],[2,3],[2,4],[3,1],[3,2],[3,4]]
a.combination(2).to_a #=> [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
a.each_slice(2) {|a| p a} #=> ["1", "2"],["3", "4"]
No, but you can do it with a combination of a few methods.
a.each_cons(2).map(&:join)
# => ["12", "23", "34"]

Sort array of numbers in Scientific Notation

I would like to sort an array of numbers (in scientific notation) from the smallest to the highest.
This is what I have tried (in vain):
require 'bigdecimal'
s = ['1.8e-101','1.3e-116', '0', '1.5e-5']
s.sort { |n| BigDecimal.new(n) }.reverse
# Results Obtained
# => [ "1.3e-116", "1.8e-101", "0", "1.5e-5" ]
# Expected Results
# => [ "0", "1.3e-116", "1.8e-101", "1.5e-5"]
The block of Enumerable#sort is expected to return -1, 0 or 1. What you want is Enumerable#sort_by:
s.sort_by { |n| BigDecimal.new(n) }
# => ["0", "1.3e-116", "1.8e-101", "1.5e-5"]
Another option is to use BigDecimal#<=> within sort:
s.sort { |x, y| BigDecimal(x) <=> BigDecimal(y) }
#=> ["0", "1.3e-116", "1.8e-101", "1.5e-5"]

Array elements to integers

I have an array of strings containing numbers:
array = ["1", "2", "3"]
I want to convert every string in the array to an integer.
array.each { |n| n.to_i } does not work, because
p array.inject(:+)
returns "123" (string) rather than 6 (integer)
array = ["1", "2", "3"]
new_array = array.map { |n| n.to_i }
p new_array.inject(:+)
=> 6
one-line solution:
array.map(&:to_i).inject(:+)
# => 6

Converting an array into a hash with format { value => position_in_array }

I have an array of numbers in string format, and I want to convert them into a hash where the keys are the numbers and the values are the positions of those numbers in the array. So for example:
["1", "5", "3"]
should result in:
{ 1 => 0, 5 => 1, 3 => 2 }
I have the following code, which works:
my_hash = {}
my_array.each do |number_string|
my_hash[number_string.to_i] = my_array.index(number_string)
end
which iterates through the array and pushes each value and its position into the hash.
Is there a shorter and more elegant way to do it? Maybe something similar to Ruby's to_a function, but more like to_h(options).
Hash[["1", "5", "3"]
.map.with_index{|e, i| [e.to_i, i]}]
# => {1=>0, 5=>1, 3=>2}
or
["1", "5", "3"]
.each_with_object({}).with_index{|(e, h), i| h[e.to_i] = i}
# => {1=>0, 5=>1, 3=>2}
arr = ["1", "5", "3"]
ha = Hash[arr.map.with_index {|a, i| [a.to_i, i]}]
puts "ha: #{ha.inspect}"
irb(main):038:0> arr=["1", "5", "3"]
=> ["1", "5", "3"]
irb(main):039:0> Hash[arr.map.with_index {|a, i| [a, i]}]
=> {"1"=>0, "5"=>1, "3"=>2}
irb(main):040:0> Hash[arr.map.with_index {|a, i| [a.to_i, i]}]
=> {1=>0, 5=>1, 3=>2}

Resources