1

I am just learning Ruby and started working with arrays. I have an array that looks like:

easyStats = [<SampleArray: @id=0, @stats=#<OpenStruct total_sessions_played=244, total_sessions_lost=124>>, 
             <SampleArray: @id=1, @stats=#<OpenStruct total_sessions_played=204, total_sessions_lost=129>>, 
             <SampleArray: @id=2, @stats=#<OpenStruct total_sessions_played=2, total_sessions_lost=4>>]

I can sort the array by the id (Integer) attribute as such:

easyStats.sort_by(&:id)

However, what I would like to do is sort the array by a key of the OpenStruct object, I have tried the following options with different errors:

easyStats.sort_by(&:stats)

Error: comparison of OpenStruct with OpenStruct failed

easyStats.sort_by(&:stats[:total_sessions_played])

Error: no implicit conversion of Symbol into Integer

easyStats[:stats].sort_by(&:total_sessions_played)

Error: no implicit conversion of Symbol into Integer

I have seen solutions on how to sort an array of just one OpenStruct object and I think I understand it - How to sort a ruby array by two conditions

Could someone show me how to sort by any key of the OpenStruct object in this example (Array with Integer and OpenStruct objects)?

Community
  • 1
  • 1
Axel
  • 15
  • 3

2 Answers2

4

The sort_by method takes a block and uses the return value of that block as the key to sort by. In your case, you can access that value by doing:

easyStats.sort_by { |i| i.stats.total_sessions_played }

The .sort_by(&:key) code is really just shorthand for .sort_by { |i| i.key }. And you can only use it when the block consists of a single method called on the block argument. You can read more about how and why it works here.

Community
  • 1
  • 1
mlovic
  • 864
  • 6
  • 11
2

You should provide an actual block (since you are calling two methods on each item consecutively):

easyStats.sort_by{|x| x.stats.total_sessions_played}

So you can't really use a short notation with & here.

potashin
  • 44,205
  • 11
  • 83
  • 107