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
Link_To Method and Click Event in Rails
Rails 4: How to Reset Test Database
Disable a Group of Tests in Rspec
Why Do I Need to Work Harder to Make My Rails Application Fit into a Restful Architecture
Are There Any Ipython-Like Shells for Ruby or Rails
Rails 4 Before_Action, Pass Parameters to Invoked Method
Modifying Database Ids from Rails Console
How to Manage Ruby Threads So They Finish All Their Work
How to Get the Intersection, Union, and Subset of Arrays in Ruby
How to Create a Copy of Some Columns of a CSV File in Ruby with Different Data in One Column
Ruby Convert Array into Function Arguments
Ruby Way to Generate a Hmac-Sha1 Signature for Oauth
Engine's Assets with Rails 3.1
Programming Technique: How to Create a Simple Card Game
Is It Idiomatic Ruby to Add an Assert( ) Method to Ruby's Kernel Class