Ruby - Elegantly Convert Variable to an Array If Not an Array Already

Ruby - elegantly convert variable to an array if not an array already

[*foo] or Array(foo) will work most of the time, but for some cases like a hash, it messes it up.

Array([1, 2, 3])    # => [1, 2, 3]
Array(1) # => [1]
Array(nil) # => []
Array({a: 1, b: 2}) # => [[:a, 1], [:b, 2]]

[*[1, 2, 3]] # => [1, 2, 3]
[*1] # => [1]
[*nil] # => []
[*{a: 1, b: 2}] # => [[:a, 1], [:b, 2]]

The only way I can think of that works even for a hash is to define a method.

class Object; def ensure_array; [self] end end
class Array; def ensure_array; to_a end end
class NilClass; def ensure_array; to_a end end

[1, 2, 3].ensure_array # => [1, 2, 3]
1.ensure_array # => [1]
nil.ensure_array # => []
{a: 1, b: 2}.ensure_array # => [{a: 1, b: 2}]

Convert array to single object if array is a single object

basically you should stick to what you wrote - it's simple and does what it should.

of course you may always monkey patch the Array definition... (unrecommended, but it does what you expect)

class Array
def first_or_array
length > 1 ? self : self[0]
end
end

[1].first_or_array # 1
[1, 2].first_or_array # [1, 2]

Return an array with integers in stead of strings

newArray <<"#{total}" # WRONG

You're pushing strings into the array with the expectation of getting integers in the end. Change the above line to:

newArray << total

And just FYI, you can use map to clean things up here.

def your_method(array)
array.map.with_index do |element, index|
element + index
end
end

Convert an empty array to nil inplace

I wasn't able to find the answer using a search engine, but StackOverflow gave me the answer with a similar question, but then about strings:

Converting an empty string to nil in place?

The solution is to use presence

Only available within Rails.

Ruby's array min returning value, not array

If you read the rest of the specification:

With no argument and (a block/no block), returns the element in self having the minimum value per (the block/method <=>):

The only case when it returns more than one element is if you specify the number of elements that you want returned:

With an argument n and (a block/no block), returns a new Array with at most n elements, in ascending order per (the block/method <=>):

[0, 1, 2, 3].min(3) # => [0, 1, 2]

Using each for object with an array of objects

In ruby we do chain methods to accomplish different complicated transforms:

@cars.map do |car|
[car.id, car.mileage]
end.each do |id, mileage|
...
end

Ruby: Object.to_a replacement

Use the method Kernel#Array:

Array([1,2,3]) #=> [1, 2, 3]
Array(123) #=> [123]

Yes it may look like a class at first but this is actually a method that starts with a capital letter.



Related Topics



Leave a reply



Submit