Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

arrays

ruby

Given an array, a single element, or nil, obtain an array - the latter two being a single element array and an empty array respectively.

I mistakenly figured Ruby would work this way:

[1,2,3].to_a  #= [1,2,3]     # Already an array, so no change 1.to_a        #= [1]         # Creates an array and adds element nil.to_a      #= []          # Creates empty array 

But what you really get is:

[1,2,3].to_a  #= [1,2,3]         # Hooray 1.to_a        #= NoMethodError   # Do not want nil.to_a      #= []              # Hooray 

So to solve this, I either need to use another method, or I could meta program by modifying the to_a method of all classes I intend to use - which is not an option for me.

So a Method it is:

result = nums.class == "Array".constantize ? nums : (nums.class == "NilClass".constantize ? [] : ([]<<nums)) 

The problem is that it is a bit of a mess. Is there an elegant way of doing this? (I would be amazed if this is the Ruby-ish way to solve this problem)


What applications does this have? Why even convert to an array?

In Rails' ActiveRecord, calling say, user.posts will either return an array of posts, a single post, or nil. When writing methods which work on the results of this, it is easiest to assume that the method will take an array, which may have zero, one, or many elements. Example method:

current_user.posts.inject(true) {|result, element| result and (element.some_boolean_condition)} 
like image 964
xxjjnn Avatar asked Aug 21 '13 13:08

xxjjnn


People also ask

How do I convert a string to an array in Ruby?

The general syntax for using the split method is string. split() . The place at which to split the string is specified as an argument to the method. The split substrings will be returned together in an array.

What does .first do Ruby?

The first() is an inbuilt method in Ruby returns an array of first X elements. If X is not mentioned, it returns the first element only. Parameters: The function accepts X which is the number of elements from the beginning. Return Value: It returns an array of first X elements.

What is TO_A in Ruby?

The to_a() is an inbuilt method in Ruby returns an array containing the numbers in the given range. Syntax: range1.to_a() Parameters: The function accepts no parameter. Return Value: It returns an array containing all the numbers.


Video Answer


1 Answers

[*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}] 
like image 53
sawa Avatar answered Oct 13 '22 07:10

sawa