简体   繁体   中英

Ruby sort_by array of hashes

I have an array of hashes that I'd like to be able to sort alphabetically on one of the values.

Array of hashes:

[{"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"test"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"batch update testing"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"test"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"batch update testing"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"test"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"batch update testing"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"test"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"batch update testing"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"test"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"batch update testing"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"test"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"batch update testing"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"test"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"batch update testing"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>22, "field_string"=>"c next"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>33, "field_string"=>"d next"}]

After running sort_by:

records.sort_by { |rec| rec[:field_string]}
=> [{"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"test"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"batch update testing"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"test"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"batch update testing"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"test"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"batch update testing"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"test"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"batch update testing"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"test"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"batch update testing"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"test"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"batch update testing"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"test"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"batch update testing"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>22, "field_string"=>"c next"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>33, "field_string"=>"d next"}]

It sorts correctly for the field_int column, but I cannot understand why it's not working correctly with the field_string. If anyone has any ideas I'd really appreciate hearing them.

Thanks!

The keys in your hashes are strings and not symbols.

records[0][:field_string] is nil

records[0]["field_string"] is "test"

So your sort is comparing nils to nils, and keeps the original order.

You need:

records.sort_by { |rec| rec["field_string"]}

It outputs:

=> [{"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"batch update testing"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"batch update testing"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"batch update testing"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"batch update testing"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"batch update testing"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"batch update testing"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"batch update testing"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>22, "field_string"=>"c next"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>33, "field_string"=>"d next"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"test"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"test"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"test"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"test"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"test"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"test"},
 {"hidden"=>false, "id"=>"5f898f7784743992f24fcb51", "field_int"=>11, "field_string"=>"test"}]

It can be confusing, because HashWithIndifferentAccess also exists.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM