根据条件对哈希进行排序

时间:2017-11-22 00:43:17

标签: ruby sorting

我有这样的哈希:

roles = {
   "teachers"   => [{name: "A"}, {name: "B"}, {name: "C"}], 
   "electrician"=> [{name: "D"}, {name: "E"}, {name: "F"}],
   "painters"   => [{name: "G"}, {name: "H"}, {name: "I"}],
   "carpenters" => [{name: "J"}, {name: "K"}, {name: "L"}],
   "gardeners"  => [{name: "P"}, {name: "Q"}, {name: "R"}], 
}

我还有一个由负面角色组成的数组negative_roles

negative_roles = ["electrician", "teachers", "carpenters"]
应该对

roles进行排序,以便所有负面角色都能在此后出现:

roles = { 
   "painters"   => [{name: "G"}, {name: "H"}, {name: "I"}],
   "gardeners"  => [{name: "P"}, {name: "Q"}, {name: "R"}], 
   "electrician"=> [{name: "M"}, {name: "N"}, {name: "O"}],
   "teachers"   => [{name: "A"}, {name: "B"}, {name: "C"}],
   "carpenters" => [{name: "J"}, {name: "K"}, {name: "L"}], 
}

我该怎么做?

2 个答案:

答案 0 :(得分:1)

以下三种方法可以重新排序哈希roles的键。在#1 roles中发生了变异。在#2和#3中,它不是。在后两种情况下,如果要修改roles(如问题所示),只需在开头插入roles =即可。同样,在#1中,如果不要对roles进行变异,请对rolesroles_cpy = roles.dup)的副本进行操作。

roles外,我们还有

negative_roles = ["electrician", "teachers", "carpenters"]

以下所有三种方法都会返回

  { "painters"=>[{:name=>"G"}, {:name=>"H"}, {:name=>"I"}],
    "gardeners"=>[{:name=>"P"}, {:name=>"Q"}, {:name=>"R"}],
    "teachers"=>[{:name=>"A"}, {:name=>"B"}, {:name=>"C"}],
    "electrician"=>[{:name=>"D"}, {:name=>"E"}, {:name=>"F"}],
    "carpenters"=>[{:name=>"J"}, {:name=>"K"}, {:name=>"L"}]}

#1使用Hash#delete

negative_roles.each { |k| roles[k] = roles.delete(k) }
roles

#2使用Hash#rejectHash#selectHash#merge

roles.reject { |k,_| negative_roles.include?(k) }.
  merge(roles.select { |k,_| negative_roles.include?(k) })

#3使用Enumerable#partition

roles.partition { |k,_| !negative_roles.include?(k) }.flatten(1).to_h

我尽量避免将哈希转换为数组,修改数组然后将其转换回哈希。这看起来有点野蛮。

答案 1 :(得分:0)

如果你知道自己的不良角色:

negative_roles = ["electrician", "teachers", "carpenters"]

你的“好”角色:

positive_roles = roles.keys - negative_roles

您可以按顺序遍历哈希:

(positive_roles + negative_roles).each do |key|
  role = roles[key]

  # ..
end

正如Beartech在上面的评论中提到的,排序哈希可能并不总是按照你想要它在Ruby中做的,但你可以将上面的内容转换为元组数组:

role_tuples = (positive_roles + negative_roles).map! { |key| [key, roles[key]] }

这看起来像:

[
  ["painters", [{:name=>"G"}, {:name=>"H"}, {:name=>"I"}]],
  ["gardeners", [{:name=>"P"}, {:name=>"Q"}, {:name=>"R"}]],
  ["electrician", [{:name=>"D"}, {:name=>"E"}, {:name=>"F"}]],
  ["teachers", [{:name=>"A"}, {:name=>"B"}, {:name=>"C"}]],
  ["carpenters", [{:name=>"J"}, {:name=>"K"}, {:name=>"L"}]]
]

如果您觉得依赖哈希维护Ruby中的顺序,则可以将其转换回哈希值(.to_h)。