Ruby:如何按特定键的给定顺序对哈希数组进行排序

时间:2014-02-10 09:18:08

标签: ruby arrays sorting hash

我有一个哈希数组,id是哈希中的一个键。我想根据ID值的给定顺序对数组元素进行排序。

假设我的数组(size = 5)是:

[{"id"=>1. ...}, {"id"=>4. ...}, {"id"=>9. ...}, {"id"=>2. ...}, {"id"=>7. ...}]

我想对数组元素进行排序,使其id按以下顺序排序:

[1,3,5,7,9,2,4,6,8,10]

所以预期的结果是:

[{'id' => 1},{'id' => 7},{'id' => 9},{'id' => 2},{'id' => 4}]

5 个答案:

答案 0 :(得分:5)

以下是任何自定义索引的解决方案:

def my_index x 
  # Custom code can be added here to handle items not in the index.
  # Currently an error will be raised if item is not part of the index.
  [1,3,5,7,9,2,4,6,8,10].index(x) 
end

my_collection = [{"id"=>1}, {"id"=>4}, {"id"=>9}, {"id"=>2}, {"id"=>7}]
p my_collection.sort_by{|x| my_index x['id'] } #=> [{"id"=>1}, {"id"=>7}, {"id"=>9}, {"id"=>2}, {"id"=>4}]

然后你可以用你想要的任何方式格式化它,也许这更漂亮:

my_index = [1,3,5,7,9,2,4,6,8,10]
my_collection.sort_by{|x| my_index.index x['id'] }

答案 1 :(得分:1)

关于排序的一般说明。使用类的#sort_by方法:

[{'id' => 1},{'id'=>3},{'id'=>2}].sort_by {|x|x['id'] }
# => [{"id"=>1}, {"id"=>2}, {"id"=>3}]

或使用#values方法作为回调:

[{'id' => 1},{'id'=>3},{'id'=>2}].sort_by(&:values)
# => [{"id"=>1}, {"id"=>2}, {"id"=>3}]

或者您可以使用#sort方法使用更明显的版本:

[{'id' => 1},{'id'=>3},{'id'=>2}].sort {|x,y| x['id'] <=> y['id'] }
# => [{"id"=>1}, {"id"=>2}, {"id"=>3}]

对于您的情况,要使用扩展条件进行排序,请使用#%来拆分偶数和奇数索引:

[{'id' => 1},{'id'=>4},{'id'=>9},{'id'=>2},{'id'=>7}].sort do |x,y|
    u = y['id'] % 2 <=> x['id'] % 2
    u == 0 && y['id'] <=> x['id'] || u 
end
# => [{"id"=>1}, {"id"=>7}, {"id"=>9}, {"id"=>2}, {"id"=>4}]

对于您的情况,要使用扩展条件进行排序,请使用#%根据索引进行拆分,索引数组中不存在id值:

index = [1,3,5,7,4,2,6,8,10] # swapped 2 and 4, 9 is absent

[{'id' => 1},{'id'=>4},{'id'=>9},{'id'=>2},{'id'=>7}].sort do |x,y|
   !index.rindex( x[ 'id' ] ) && 1 || index.rindex( x[ 'id' ] ) <=> index.rindex( y[ 'id' ] ) || -1 
end
# => [{"id"=>1}, {"id"=>7}, {"id"=>4}, {"id"=>2}, {"id"=>9}]

答案 2 :(得分:1)

我会根据这样的值映射哈希:

a = [{"id"=>1}, {"id"=>4}, {"id"=>9}, {"id"=>2}, {"id"=>7}]

[1,3,5,7,9,2,4,6,8,10].map{|x| a[a.index({"id" => x})] }.compact

#=> [{"id"=>1}, {"id"=>7}, {"id"=>9}, {"id"=>2}, {"id"=>4}]

答案 3 :(得分:0)

为什么不只是sort

def doit(arr, order)
  arr.sort { |h1,h2| order.index(h1['id']) <=> order.index(h2['id']) }
end

order = [1,3,5,7,9,2,4,6,8,10]
arr = [{'id' => 1}, {'id' => 4}, {'id' => 9}, {'id' => 2}, {'id' => 7}]     

doit(arr, order)
  #=> [{'id' => 1}, {'id' => 7}, {'id' => 9}, {'id' => 2}, {'id' => 4}]     

答案 4 :(得分:0)

a= [{"id"=>1}, {"id"=>4}, {"id"=>9}, {"id"=>2}, {"id"=>7}]
b=[1,3,5,7,9,2,4,6,8,10]
a.sort_by{|x| b.index (x['id'])}