【问题标题】:Ruby - Sorting by id and grouping by date in hashRuby - 在哈希中按 id 排序和按日期分组
【发布时间】:2020-02-13 09:51:17
【问题描述】:

我一直在为此苦苦挣扎,无法获得令人满意的结果。我有这个哈希:

{"idprj"=>13351, "prevInicioStr"=>"21/10/2019"}
{"idprj"=>14473, "prevInicioStr"=>"22/10/2019"}
{"idprj"=>14165, "prevInicioStr"=>"23/10/2019"}
{"idprj"=>14165, "prevInicioStr"=>"23/10/2019"}
{"idprj"=>14165, "prevInicioStr"=>"28/10/2019"}
{"idprj"=>14165, "prevInicioStr"=>"28/10/2019"}
{"idprj"=>14518, "prevInicioStr"=>"29/10/2019"}
{"idprj"=>14518, "prevInicioStr"=>"29/10/2019"}
{"idprj"=>13351, "prevInicioStr"=>"05/11/2019"}
{"idprj"=>14305, "prevInicioStr"=>"06/11/2019"}
{"idprj"=>14305, "prevInicioStr"=>"08/11/2019"}
{"idprj"=>14305, "prevInicioStr"=>"13/01/2020"}

我想按“prevInicioStr”排序并按“idprj”分组(您可以看到 id 13351 没有按应有的方式分组)。为了得到这个结果,我这样做了:

result.sort_by { |hash| [ Date.parse(hash['prevInicioStr']), hash['idprj'] ] } 

【问题讨论】:

  • 那是 12 个哈希,而不是一个。你的意思是它是一个哈希数组吗?如果是这样(即使您选择了答案),请进行编辑以使其如此。此外,如果您将变量分配给数组(例如,arr = [{...}, {...},...,{...}]),这将很有帮助,这样读者就可以在答案和 cmets 中引用该变量而无需定义它。另外,您为什么选择提供的第一个答案?你不想见别人?
  • 我选择了作为回答,因为它符合我的需要,但是嘿,也欢迎大家发表评论!

标签: ruby sorting hash grouping


【解决方案1】:

你必须先分组,然后排序(实际上是对值进行排序):

data = [{"idprj"=>13351, "prevInicioStr"=>"21/10/2019"}, {"idprj"=>14473, "prevInicioStr"=>"22/10/2019"}, {"idprj"=>14165, "prevInicioStr"=>"23/10/2019"}, {"idprj"=>14165, "prevInicioStr"=>"23/10/2019"}, {"idprj"=>14165, "prevInicioStr"=>"28/10/2019"}, {"idprj"=>14165, "prevInicioStr"=>"28/10/2019"}, {"idprj"=>14518, "prevInicioStr"=>"29/10/2019"}, {"idprj"=>14518, "prevInicioStr"=>"29/10/2019"}, {"idprj"=>13351, "prevInicioStr"=>"05/11/2019"}, {"idprj"=>14305, "prevInicioStr"=>"06/11/2019"}, {"idprj"=>14305, "prevInicioStr"=>"08/11/2019"}, {"idprj"=>14305, "prevInicioStr"=>"13/01/2020"}]
pp data.group_by { |e| e['idprj'] }
       .transform_values { |values| values.sort_by { |e| e['prevInicioStr'] } }

# {13351=>
#   [{"idprj"=>13351, "prevInicioStr"=>"05/11/2019"},
#    {"idprj"=>13351, "prevInicioStr"=>"21/10/2019"}],
#  14473=>[{"idprj"=>14473, "prevInicioStr"=>"22/10/2019"}],
#  14165=>
#   [{"idprj"=>14165, "prevInicioStr"=>"23/10/2019"},
#    {"idprj"=>14165, "prevInicioStr"=>"23/10/2019"},
#    {"idprj"=>14165, "prevInicioStr"=>"28/10/2019"},
#    {"idprj"=>14165, "prevInicioStr"=>"28/10/2019"}],
#  14518=>
#   [{"idprj"=>14518, "prevInicioStr"=>"29/10/2019"},
#    {"idprj"=>14518, "prevInicioStr"=>"29/10/2019"}],
#  14305=>
#   [{"idprj"=>14305, "prevInicioStr"=>"06/11/2019"},
#    {"idprj"=>14305, "prevInicioStr"=>"08/11/2019"},
#    {"idprj"=>14305, "prevInicioStr"=>"13/01/2020"}]}

【讨论】:

  • 看起来不错,唯一的就是按日期排序。使用.sort_by { |e| Date.strptime(e['prevInicioStr'], '%d/%m/%Y') }之类的东西会不会更好
  • 那很好,但我不知道是否需要它,因为p "05/11/2019" <=> "21/10/2019" # -1; p "21/10/2019" <=> "05/11/2019" # 1; p "21/10/2019" <=> "21/10/2019" # 0
  • 完成!刚刚删除了我代码中的键,只让值和一切都很好!
  • @SebastianPalma 在 iso8601 格式中不需要它,因为日期以另一个方向表示。目前,您按天排序,然后按月排序,然后按年排序。这意味着"01/01/2050""06/01/1850" 之前,因为"01" 小于"06"
猜你喜欢
  • 2018-11-15
  • 1970-01-01
  • 2017-03-24
  • 1970-01-01
  • 1970-01-01
  • 2015-11-18
  • 2011-05-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多