开发者

Ruby: Best way to parse a conditional array element

I'm doing API calls that will conditionally return a couple differ开发者_StackOverflow中文版ent 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.


A better way :

value = array['productId'][0] if array['productId']

However, array['productId'][0] is not ruby natural. What does your array consist of ?


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


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.


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).


You could use a ternary:

   value = array['productId'].nil?  ? nil : array['productId'][0]


Your code pattern looks OK; it's possible to be slightly shorter...

value = (t = x['productId']) && t[0]


Using the maybe pattern of Ick, terse and explicit:

value = array['productId'].maybe[0]


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].


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!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜