ruby: how to convert hash into array - ruby

I have a hash that contains numbers as such:
{0=>0.07394653730860076, 1=>0.0739598476853163, 2=>0.07398647083461522}
it needs to be converted into an array like:
[[0, 0.07394653730860076], [1, 0.0739598476853163], [2, 0.07398647083461522]]
i tried my hash.values which gets me:
[0.07398921877505593, 0.07400253683443543, 0.07402917535044515]
I have tried multiple ways but i just started learning ruby.

try this:
{0=>0.07394653730860076, 1=>0.0739598476853163, 2=>0.07398647083461522}.to_a
#=> [[0, 0.07394653730860076], [1, 0.0739598476853163], [2, 0.07398647083461522]]

Definitely use the Hash#to_a method, which will produce exactly what you are looking for.
{0=>0.07394653730860076, 1=>0.0739598476853163, 2=>0.07398647083461522}.to_a
=> [[0, 0.07394653730860076], [1, 0.0739598476853163], [2, 0.07398647083461522]]
Hash#values will give you only the values of each element in the hash, while Hash#keys will give you just the keys. Fortunately, the default behavior of to_a is what you are looking for.

Related

Ruby equivalent to Python's "array[i:]" to select all array elements after i?

I find myself wanting something like Python's
ary = [1,2,3,4,5,6,7,8]
ary[2:] #=> [3,4,5,6,7,8]
ALL of the time these days.
The solution always ends up being multi-lined and ugly. I'm wondering what the most elegant solutions out there might be, because mine are not worth showing.
Use Array#drop
2.1.0 :019 > ary.drop(2)
=> [3, 4, 5, 6, 7, 8]
You can write:
ary[2..-1]
# => [3,4,5,6,7,8]
-1 is the index of the last element in the array, see the doc for Array#[] for more informations.
A better alternative in Ruby is to use the Array#drop method:
ary.drop(2)
# => [3,4,5,6,7,8]

Is there a way to split an array of objects in Rails by two different delimiters?

I would like to do something like this:
#residenciais, #comerciais = TipoImovel.all.split { |t| t.residencial? }
The problem is that #comerciais is always empty because it never returns the object, since the condition is false.
Is there a better way of doing this?
You're looking for the standard method Enumerable#partition, rather than the Rails split add-on.
#residenciais, #comerciais = TipoImovel.all.partition { |t| t.residencial? }
Which can also be written like this, since the condition is a single method call:
#residenciais, #comerciais = TipoImovel.all.partition(&:residencial?)
Some more explanation:
The Rails Array#split method is used to separate an array into ordered groups delimited by elements which return true for a given block. It's a generalization of the standard String method. For example:
[1,2,3,4,5,6].split(&:odd?) #=> [[], [2], [4], [6]]
Any odd number is a delimiter, so it returns the portions of the array between the odd numbers, in order.
Whereas this is closer to what you're doing:
odds, evens = [1,2,3,4,5,6].partition(&:odd?) #=> [[1, 3, 5], [2, 4, 6]]
If the partition condition is not simply Boolean, or if you want to key off the values regardless, then you can use Enumerable#group_by, which returns a Hash of Arrays instead of a pair:
[1,2,3,4,5,6].group_by(&:odd?) #=> {true=>[1, 3, 5], false=>[2, 4, 6]}
You can use group_by:
#residenciais, #comerciais = TipoImovel.all.group_by { |t| t.residencial }.values

Ruby hash to array convert

I have something like this:
[#TrajectoryMeasurement depth: 0, move_e: 234>,
#TrajectoryMeasurement depth: 1475, move_e: 123>]
How to convert it to:
[[0, 234], [1475,123]]
If it's an array of objects as I suspect you can use the #collect method on Array:
array = [#TrajectoryMeasurement depth: 0, move_e: 234>,
#TrajectoryMeasurement depth: 1475, move_e: 123>]
array.collect { |x| [x.depth, x.move_e] }
# => [[0, 234], [1475, 123]]
Supposing you really had a hash, all you need is calling .to_a to get exactly what you asked for.
{a:1, b:1}.to_a
=> [[:a, 1], [:b, 1]]
Alas, as it was said before, it wouldn't see, what you have there is a Hash, unless that's an ad-hoc representation of it.
Depending on the structure of your hash you might also want to have a look at .flatten.

Ruby remove nil values from array with .reject

I have an array:
scores = [1, 2, 3, "", 4]
And I want to remove all blank values. But when I run this:
puts scores.reject(&:empty?)
I get an error:
undefined method `empty' for 1:Fixnum
How can I remove values that are not integers from my array in a one step process? I am using Ruby 1.9.3.
To reject only nil would be:
array.compact
If you want to remove blank values, you should use blank?: (requires Rails / ActiveSupport)
scores.reject(&:blank?)
#=> [1, 2, 3, 4]
"", " ", false, nil, [], and {} are blank.
It is as simple as:
scores.grep(Integer)
Note that if you plan to map the values, you can do that in a block after:
scores.grep(Integer){|x| x+1 }
Bonus if you want to do the same thing, but your numbers are strings:
scores.grep(/\d+/){|x|x.to_i}
Try this :
scores.select{|e| e.is_a? Integer}
# => [1, 2, 3, 4]
If you really need reject nil only, so it can be done like this:
scores.reject(&:nil?)
scores = [1, 2, 3, "", 4, nil]
scores.reject{|s| s.to_s == ''}
# => [1, 2, 3, 4]
This Worked for me
scores.reject!{|x| x.to_s.empty?}
scores.select{|score| score.is_a? Fixnum}
or, as Fixnum inherits from Integer, you can also go for
scores.select{|score| score.is_a? Integer)
...if that seems more descriptive.
Array and Enumerable tend to offer many ways of doing the same thing.
&:empty? will work for hashes, arrays, and strings, but not numbers. The method you use in reject must be valid for all items in a list. &:blank? will work fine for this reason.

Ruby Regex: Get Index of Capture

I've seen this question asked and answered for javascript regex, and the answer was long and very ugly. Curious if anyone has a cleaner way to implement in ruby.
Here's what I'm trying to achieve:
Test String: "foo bar baz"
Regex: /.*(foo).*(bar).*/
Expected Return: [[0,2],[4,6]]
So my goal is to be able to run a method, passing in the test string and regex, that will return the indices where each capture group matched. I have included both the starting and ending indices of the capture groups in the expected return. I'll be working on this and adding my own potential solutions here along the way too. And of course, if there's a way other than regex that would be cleaner/easier to achieve this, that's a good answer too.
Something like this should work for a general amount of matches.
def match_indexes(string, regex)
matches = string.match(regex)
(1...matches.length).map do |index|
[matches.begin(index), matches.end(index) - 1]
end
end
string = "foo bar baz"
match_indexes(string, /.*(foo).*/)
match_indexes(string, /.*(foo).*(bar).*/)
match_indexes(string, /.*(foo).*(bar).*(baz).*/)
# => [[0, 2]]
# => [[0, 2], [4, 6]]
# => [[0, 2], [4, 6], [8, 10]]
You can have a look at the (kind of strange) MatchData class for how this works. http://www.ruby-doc.org/core-1.9.3/MatchData.html
m = "foo bar baz".match(/.*(foo).*(bar).*/)
[1, 2].map{|i| [m.begin(i), m.end(i) - 1]}
# => [[0, 2], [4, 6]]

Resources