0

I have a hash like this (it is the result of the group_by method):

{nil => [#<ActiveRecord id ..., ...], #<ActiveRecord ...> => [#<ActiveRecord id ..., ...], ...}

I need to sort it so that the nil elements would be the first, and then all the other ActiveRecord objects. How can I do this? Thanx

P.S.

  1. Yes, I need an ActiveRecord objects as the keys (not symbols or some else)
  2. I can't do the order in my DB due to complex SQL request.

I need only to sort the hash by the keys.

2
  • Here are suggestions for how this question could have been improved. I offer them mainly to help you write questions in future. 1) When you give in an example, make it complete and give objects names. 2) Make the example as small and as simple as possible. Here, the fact that most objects in your hash are instances is irrelevant to the question, so make them something simpler (and sortable), so that readers could use it in testing and comparing code. Here you might use strings. (cont.) Commented Mar 4, 2015 at 19:33
  • (cont.) 3. When you give an example, always give your desired output. So here perhaps something like hash = { nil=> ["dog", "cat"], "pig"=>["zebra", "sloth"], "groundhog"=>["toad", "ladybug"] } (though I didn't read your question closely enough to know if that would make sense). I see in your comment to @Stefan's answer that you are sorting on string representations of ActiveRecord objects. I don't think those answering were expecting you wanted to do that, because such objects do not respond to <=>. Commented Mar 4, 2015 at 19:38

2 Answers 2

1

You cannot sort a hash, but:

Hashes enumerate their values in the order that the corresponding keys were inserted.

To get a specific key at the beginning, just make sure to insert it first. Here's an example:

array = [Integer, Range, BasicObject]

hash = array.group_by(&:superclass)
#=> {Numeric=>[Integer], Object=>[Range], nil=>[BasicObject]}

To get nil first, create a hash with a nil key and merge! the new values:

hash = {nil => nil}
hash.merge!(array.group_by(&:superclass))
#=> {nil=>[BasicObject], Numeric=>[Integer], Object=>[Range]}
Sign up to request clarification or add additional context in comments.

1 Comment

I need to group my elements by an ActiveRecord association. And I don't know if nil first or the last key of my group_by result. Now I'm doing something like this: sort_by { |i, _| i.to_s } and it works, but it is a sticky hack
0

Assuming you have your hash in h:

Hash[h.sort { |a,b| 
  NilClass === a.first ? 
      (NilClass === b.first ? 0 : -1) : 
      (NilClass === b.first ? 1 : a.first <=> b.first) 
}]

Here we explicitly define sort function, which will place nils in front, following by native ordering of other elements by keys (ActiveRecord instances in your case.)

Sidenote: you always can do sorting in database.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.