2

我想按 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: {...} 
}

实现这一目标的最 Ruby-ish 方式是什么?

4

3 回答 3

3

类似于@sawa,但使用 Hash#values 真的可以清理恕我直言:

keys = Hash1.values.map &:to_sym
Hash[Hash2.sort_by{|k, v| keys.index(k) || keys.length}]
于 2012-10-19T08:28:06.980 回答
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将被用作参考,这意味着你想用它的“索引”做一些事情。由于哈希没有索引的概念,因此您必须将其转换为array. to_a这样做。接下来,您要按Hash2索引的顺序排序(这意味着它将隐式转换为具有键值对的数组),以array使 的键Hash2与 的“值”匹配arrayindex{...}会查找这样的索引。如果没有匹配,array.length将被分配,它比任何索引都大array。最后,您希望将这对键值对转换回散列。这是由Hash[...].

于 2012-10-19T03:00:54.927 回答
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}
于 2012-10-19T03:07:15.250 回答