Put the index first with each_with_index - ruby

I am using Array() with each_with_index to output a array with index but I want it to output
[[0,obj1],[1,obj2]....]
whereas each_with_index makes it output
[[obj1,0],[obj2,1]....]
Is there anyway this can be fixed easilly?
As been asked to show code.
Array(test.each_with_index)

Try adding .map { |x| x.reverse } after the each_with_index.

Use this:
[obj1, obj2, ..., objN].map.with_index{|a,i| [i,a] }
#=> [[0, obj1], [1, obj2], ..., [N-1, objN]]

Related

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 Hash - sort by value and print keys

This is my hash.
=> {"f11"=>1, "f12"=>3, "f13"=>3, "f07"=>5, "f10"=>1}
I'd like to sort by the values largest to smallest and then make an array out of the keys.
=> ["f07", "f12", "f13", "f11", "f10"]
Here's a one-liner for you (I love ruby!):
h.keys.sort {|a, b| h[b] <=> h[a]}
Hope that helps!
Hash has the Enumerable module mixed in which provides us with methods like sort and sort_by.In this situation we can use sort_by to get a collection by order of values.
h={"f11"=>1, "f12"=>3, "f13"=>3, "f07"=>5, "f10"=>1}
h.sort_by{ |key, value| -value }
=> [["f07", 5], ["f12", 3], ["f13", 3], ["f11", 1], ["f10", 1]]
Even shorter!:
h.keys.sort_by{|a| h[a]}.reverse
a = {"f11"=>1, "f12"=>3, "f13"=>3, "f07"=>5, "f10"=>1}
b = Hash[a.sort_by{|k,v| v}]
puts b.keys.reverse

Why does Array#each return an array with the same elements?

I'm learning the details of how each works in ruby, and I tried out the following line of code:
p [1,2,3,4,5].each { |element| el }
And the result is an array of
[1,2,3,4,5]
But I don't think I fully understand why. Why is the return value of each the same array? Doesn't each just provide a method for iterating? Or is it just common practice for the each method to return the original value?
Array#each returns the [array] object it was invoked upon: the result of the block is discarded. Thus if there are no icky side-effects to the original array then nothing will have changed.
Perhaps you mean to use map?
p [1,2,3,4,5].map { |i| i*i }
If you want, for some reason, to suppress the output (for example debugging in console) here is how you can achive that
[1,2,3,4,5].each do |nr|
puts nr.inspect
end;nil
Array#each
The block form of Array#each returns the original Array object. You generally use #each when you want to do something with each element of an array inside the block. For example:
[1, 2, 3, 4, 5].each { |element| puts element }
This will print out each element, but returns the original array. You can verify this with:
array = [1, 2, 3, 4, 5]
array.each { |element| element }.object_id === array.object_id
=> true
Array#map
If you want to return a new array, you want to use Array#map or one of its synonyms. The block form of #map returns a different Array object. For example:
array.object_id
=> 25659920
array.map { |element| element }.object_id
=> 20546920
array.map { |element| element }.object_id === array.object_id
=> false
You will generally want to use #map when you want to operate on a modified version of the original array, while leaving the original unchanged.
All methods return something. Even if it's just a nil object, it returns something.
It may as well return the original object rather than return nil.

How can I reject values from one array based on a parallel array?

Given
number_strings = ["ichi", "ni", "san", "ku"]
fixnums = [1, 2, 3, 9]
how would I get a list of number_strings where the corresponding fixnum is not even?
number_strings.reject.each_with_index do |string, index|
fixnums.fetch(index).even?
end
works, as does
pairs = number_strings.zip(fixnums)
pairs.reject{|_, fixnum| fixnum.even?}.map(&:first)
but both are a bit verbose.
I think they all come out quite verbose really.
Hash[number_strings.zip(fixnums)].select { |k, v| v.odd? }.keys
I actually think your solutions are fine, the only alternative I can come up with is this and that's as verbose:
number_strings.zip(fixnums).map { |str, fn| str if fn.odd? }.compact
Use fix and select:
fixnums.zip(number_strings).select { |k, v| k.odd? }.map(&:last)
=> ["ichi", "san", "ku"]
In Ruby 1.9 you can do:
number_strings = ["ichi", "ni", "san", "ku"]
fixnums = [1, 2, 3, 9]
enum = fixnums.each
number_strings.select{ enum.next.odd? }
You are right to think it's a bit verbose, and that's because Ruby has no syntax for list-comprehensions. A simple abstracion like Enumerable#comprehend -if not as beautiful- comes pretty close (comprehend = map+compact):
number_strings.zip(fixnums).comprehend { |s, n| s if n.odd? }

Resources