通过另一个哈希中的值对哈希进行排序

时间:2012-10-19 02:46:42

标签: ruby sorting hash key

我想按Hash1值的顺序对Hash2的键进行排序。 Hash2不需要包含Hash1的所有值。 Hash1不需要包含Hash2的所有键。 如果Hash2中存在一个在Hash1中没有相应值的密钥,则应该在任何现有的有序密钥下面进行排序。

Hash1 = {
    p0: "q11",
    p1: "q55",
    p2: "q92",
    p3: "q77"

}

Hash2 = {
    q55: {...},
    q23: {...},
    q59: {...},
    q98: {...},
    q11: {...}
}

=>
DesiredHash = {
    q11: {...},
    q55: {...},
    q23: {...},
    q59: {...},       
    q98: {...} 
}

实现这一目标的最直接的方式是什么?

3 个答案:

答案 0 :(得分:3)

与@ sawa类似,但使用Hash#值确实可以清除imho:

keys = Hash1.values.map &:to_sym
Hash[Hash2.sort_by{|k, v| keys.index(k) || keys.length}]

答案 1 :(得分:2)

array = Hash1.map{|k, v| [k, v.to_sym]}
Hash[Hash2.sort_by{|k, _| array.index{|_, v| k == v} || array.length}]

或者,效率可能更低但更短:

array = Hash1.to_a
Hash[Hash2.sort_by{|k, _| array.index{|_, v| k == v.to_s} || array.length}]

说明(使用第二个) Hash1将用作参考,这意味着您想要对其“索引”执行某些操作。由于哈希没有索引的概念,您必须将其转换为arrayto_a这样做。接下来,您希望按Hash2索引的顺序对array(这意味着它将隐式转换为具有键值对的数组)进行排序,以使Hash2的键匹配array的“价值”。 index{...}会查找此类索引。如果没有匹配项,则会分配array.length,这比array的任何索引都要大。最后,您希望将这对键值重新转换为哈希值。这是由Hash[...]完成的。

答案 2 :(得分:1)

hash1 = {
    p0: "q11",
    p1: "q55",
    p2: "q92",
    p3: "q77"

}

hash2 = {
    q55: 1,
    q23: 2,
    q59: 3,
    q98: 4,
    q11: 5
}

def get_key(hash, value)
  hash.each { |k, v| return k if v == value }
  return hash.keys.max
end

Hash[hash2.sort_by { |a, _| get_key(hash1, a.to_s) }]
#=> {:q11=>5, :q55=>1, :q23=>2, :q98=>4, :q59=>3}