What is an elegant way in Ruby to tell if a variable is a Hash or an Array?
You can just do:
@some_var.class == Hash
or also something like:
@some_var.is_a?(Hash)
It's worth noting that the "is_a?" method is true if the class is anywhere in the objects ancestry tree. for instance:
@some_var.is_a?(Object) # => true
the above is true if @some_var is an instance of a hash or other class that stems from Object. So, if you want a strict match on the class type, using the == or instance_of? method is probably what you're looking for.
Is there an elegant way to iterate through an array and stop before the end?
What you are effectively doing is, first map
ping the elements of the Array
with a transformation, and then find
ing the first transformed element that satisfies some predicate.
We can express this like this (I'm re-using the definitions from @iGian's answer, but with an added side-effect so that you can observe the evaluation of the transformation operation):
def complex_stuff_with(e)
p "#{__callee__}(#{e.inspect})"
e**2
end
ary = [1, 2, 3, 2]
x_i_want = 4
ary
.map(&method(:complex_stuff_with))
.find(&x_i_want.method(:==))
# "complex_stuff_with(1)"
# "complex_stuff_with(2)"
# "complex_stuff_with(3)"
# "complex_stuff_with(2)"
#=> 4
This gives us the correct result but not the correct side-effects. You want the operation to be lazy
. Well, that's easy, we just need to convert the Array
to a lazy enumerator first:
ary
.lazy
.map(&method(:complex_stuff_with))
.find(&x_i_want.method(:==))
# "complex_stuff_with(1)"
# "complex_stuff_with(2)"
#=> 4
Or, using the definitions from your question:
array
.lazy
.map(&method(:complex_stuff_with))
.find(&:is_the_one_i_want?)
How to determine if the contents of a text field are a hash or a string in rails using ruby?
You could
if suggestion.kind_of?(Hash)
# ...
end
or
if Hash === suggestion
# ...
end
Is there a more elegant way of writing a while loop in Ruby where the array size is not known?
Assuming your goal is to create an array of odd numbers up to a limit, you can use a range with a step.
limit = 20
array = (1..limit).step(2).to_a
EDIT
If you want to be able to descend as well as ascend you can use step
.
#Ascending
start = 1
limit = 20
array = start.step(limit, 2).to_a
#Descending
start = 20
limit = 1
array = start.step(limit, -2).to_a
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}]
Should multiple array/hash lookups be stored in a variable
So I was wondering if multiple array or hash lookups are so expensive
Expensive calls are not the only reason for not doing the call multiple times. It also clutters the code without real need. Consider this not-so-contrived example:
Order.new(
name: params[:order][:name],
total: params[:order][:total],
line_items: [
{
product_name: params[:order][:line_item][:product],
price: params[:order][:line_item][:price],
}
]
)
Even though those hash accesses are super-cheap, it still makes sense to extract them, for readability reasons.
order_params = params[:order]
line_item_params = order_params[:line_item]
Order.new(
name: order_params[:name],
total: order_params[:total],
line_items: [
{
product_name: line_item_params[:product],
price: line_item_params[:price],
}
]
)
Related Topics
Rails - Finding Intersections Between Multiple Arrays
Rails Console Running Incredibly Slowly When Editing Text
Building a Hash in a Conditional Way
Using Question Mark Character in Rails/Activerecord Column Name
How to Get Request's Target Controller and Action with Rails 3
How to Run Ruby Tasks That Use My Rails Models
How to Use One Line Regular Expression to Get Matched Content
Error About Nokogiri While Capistrano Deployment on Ubuntu Server
How to Get Files Count in a Directory Using Ruby
How to Do Standard Deviation in Ruby
How to Create a Rest API for a Ruby Application
What Is the Easiest Way I Can Create a 'Beep' Sound from a Ruby Program
How to Get an Array with Column Names of a Table
How to Add Two Weeks to Time.Now
How to Use Nokogiri to Parse an Xml File
Ruby Easy Search for Key-Value Pair in an Array of Hashes
How to Use Ruby Minitest::Spec with Rails for API Integration Tests