0

I've got an array of hashes: hashes = [{field: 'one'}, {field: 'two'}]

And I want to get the list of fields from it: ['one', 'two']

hashes.map(&:field) doesn't work, clearly, and hashes.map { |hash| hash[field] } feels a bit clunky to me.

Is there a more elegant way?

EDIT: I should clarify, I do only want the value of 'fields' in my response.

So, hashes = [{field: 'one', another: 'three'}, {field: 'two'}].do_the_thing should be ['one', 'two']

4
  • 3
    What you've come up with seams pretty reasonable. What feels clunky about it to you? Commented Nov 12, 2014 at 23:36
  • Could just be that I'm being picky, but it doesn't read in English very well, and is a little bit of an eyesore to chain. Just wondering if there's someone out there who has come up with something more clever. It's ruby, there must be more than one way, right? :) Commented Nov 12, 2014 at 23:39
  • It's only a slight improvement, but if you want something that reads a bit more nicely you could use hashes.collect - collect is an aliias for map and fits here - collecting the fields from each hash. Commented Nov 12, 2014 at 23:40
  • 3
    Your hashes.map { |hash| hash[:field] } is not just OK, it's the perfect way to do this. Note you wrote hash[field]; you need :field. Commented Nov 13, 2014 at 2:30

4 Answers 4

3

Perhaps something like the following would be more pleasing to the eye:

hashes = [{field: 'one', another: 'three'}, {field: 'two'}] fields = lambda { |hash| hash[:field] } hashes.collect(&fields) 
Sign up to request clarification or add additional context in comments.

2 Comments

It's superficially more pleasing when glancing at it, however, if someone was maintaining the code, they'd have to backtrack to find what fields was, discover it was a lambda, so then they'd understand what was going on. There's not enough noise being covered by the use of the lambda to make up for the backtracking.
@theTinMan I don't disagree: while tempting, I'd try and avoid using it outside of a small project! However, OP was after something more elegant, and later clarified to something that reads better in English, which it does.
1

Look at flat_map:

hashes = [{field: 'one'}, {field: 'two'}] hashes.flat_map(&:values) # => ["one", "two"] 

2 Comments

I probably should have been clearer; I do only want the values for 'field' in my result; this wouldn't work for say [{field: 'one', another: 'whoops!'}, {field: 'two'}]
Yes, it's pretty important to correctly/completely describe the problem otherwise people thrash around trying to provide help.
1

Not sure if this is any better, but perhaps it reads a little more clearly:

hashes.map { |hash| hash.values }.flatten

Comments

0

If you are using Rails, ActiveSupport defines Enumerable#pluck for this:

hashes = [{field: 'one'}, {field: 'two'}] hashes.pluck(:field) # => ["one", "two"] 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.