Reputation: 1064
I'm doing API calls that will conditionally return a couple different elements. My code is currently:
if array['productId']
value = array['productId'][0]
end
I feel like there is a more succinct way of doing this. Some Ruby magic.
Upvotes: 0
Views: 1393
Reputation: 111
Since Ruby 2.3.0, the shortest way is Array#dig
:
array.dig('productId', 0)
http://ruby-doc.org/core-2.3.0_preview1/Array.html#method-i-dig
Upvotes: 2
Reputation: 1515
Ha, I love all the options here. But since I didn't see what I use most, I'll add one more!
value = array['productId'] && array['productId'].first
(I prefer .first
to [0]
because it reads a little better)
This presumes you'll have an array in array['productId']
, which is the right way to do it (rather than type-checking).
Otherwise, the biggest diference between this and your original code, is that this results in value
having nil
assigned to it if the array doesn't have anything, whereas your original results in value
not being defined (which may cause errors, depending on how you use it down the road).
Hope that helps!
Upvotes: 0
Reputation: 52651
This might be a bit pedantic, but to make sure it works in all circumstances, you should not check 'not-nil', but rather that it is indexable; something like this:
value = array['productId'][0] if array['productId'].is_a? Array
Or even better:
value = array['productId'][0] if array['productId'].respond_to? '[]'
Otherwise your code will fail if array['productId'] == 2
(which on the other hand seems reasonable, given the key used - I would have gone product_ids
instead).
Upvotes: 1
Reputation: 66837
While I think your code is fine (although I'd prefer SpyrosP's one-line version), you have some possibilities:
Rails has Object#try, which would let you do either array['productId'].try(:[], 0)
or array['productId'].try(:at, 0)
.
Some people like the andand gem, which defines Object#andand
and is used like array['productId'].andand[0]
.
Upvotes: 0
Reputation: 67860
Using the maybe pattern of Ick, terse and explicit:
value = array['productId'].maybe[0]
Upvotes: 0
Reputation: 146073
Your code pattern looks OK; it's possible to be slightly shorter...
value = (t = x['productId']) && t[0]
Upvotes: 0
Reputation: 168101
I am not sure if you are using value
just temporarily or actually using it later, and what you want to do with value
when the condition is not met. If you want to return nil
for missing keys, then
array['productId'].to_a[0]
can work. Otherwise, SpyrosP's answer will be the best.
Upvotes: 1
Reputation: 48626
A better way :
value = array['productId'][0] if array['productId']
However, array['productId'][0] is not ruby natural. What does your array consist of ?
Upvotes: 4
Reputation: 6621
You could use a ternary:
value = array['productId'].nil? ? nil : array['productId'][0]
Upvotes: 0