我试图根据多个键和多个方向(ASC和DESC)对哈希数组进行排序。
假设数组如下:
items = [ {field1: '1', field2: 5, field3: 5},
{field1: '1', field2: 1, field3: 3},
{field1: '3', field2: 3, field3: 2},
{field1: '3', field2: 1, field3: 8},
{field1: '7', field2: 5, field3: 6},
{field1: '7', field2: 5, field3: 1} ]
我想创建 multiple_sort(items,options)方法,其工作方式如下:
multiple_sort(items, [{field: 'feed1', dir: 'asc'}, {field: 'feed3', dir: 'asc'}])
将生成:
[ {field1: '1', field2: 1, field3: 3},
{field1: '1', field2: 5, field3: 5},
{field1: '3', field2: 3, field3: 2},
{field1: '3', field2: 1, field3: 8},
{field1: '7', field2: 5, field3: 1},
{field1: '7', field2: 5, field3: 6} ]
并且
multiple_sort(items, [{field: 'feed1', dir: 'asc'}, {field: 'feed3', dir: 'desc'}])
将输出:
[ {field1: '1', field2: 5, field3: 5},
{field1: '1', field2: 1, field3: 3}
{field1: '3', field2: 1, field3: 8},
{field1: '3', field2: 3, field3: 2},
{field1: '7', field2: 5, field3: 6},
{field1: '7', field2: 5, field3: 1} ]
任何帮助将不胜感激。
答案 0 :(得分:2)
我冒昧地将feed1
解释为field1
,并将字符串更改为符号以提高效率。
def multiple_sort(array, criteria)
array.sort do |a, b|
cmp = 0
criteria.each do |criterion|
cmp = a[criterion[:field]] <=> b[criterion[:field]]
cmp = -cmp if criterion[:dir] == :desc
break if cmp != 0
end
cmp
end
end
require 'pp'
pp multiple_sort(items, [
{field: :field1, dir: :asc},
{field: :field3, dir: :asc}
])
# [{:field1=>"1", :field2=>1, :field3=>3},
# {:field1=>"1", :field2=>5, :field3=>5},
# {:field1=>"3", :field2=>3, :field3=>2},
# {:field1=>"3", :field2=>1, :field3=>8},
# {:field1=>"7", :field2=>5, :field3=>1},
# {:field1=>"7", :field2=>5, :field3=>6}]
pp multiple_sort(items, [
{field: :field1, dir: :asc},
{field: :field3, dir: :desc}
])
# [{:field1=>"1", :field2=>5, :field3=>5},
# {:field1=>"1", :field2=>1, :field3=>3},
# {:field1=>"3", :field2=>1, :field3=>8},
# {:field1=>"3", :field2=>3, :field3=>2},
# {:field1=>"7", :field2=>5, :field3=>6},
# {:field1=>"7", :field2=>5, :field3=>1}]
答案 1 :(得分:0)
您可以使用Enumerable#sort_by:
<强>代码强>
def multiple_sort(items, options)
items.sort_by { |h| options.map { |g|
((g[:dir]=='asc') ? 1 : -1) * h[g[:field].to_sym].to_i } }
end
<强>实施例强>
items = [ {field1: '1', field2: 5, field3: 5},
{field1: '1', field2: 1, field3: 3},
{field1: '3', field2: 3, field3: 2},
{field1: '3', field2: 1, field3: 8},
{field1: '7', field2: 5, field3: 6},
{field1: '7', field2: 5, field3: 1} ]
options = [{field: 'field1', dir: 'asc'}, {field: 'field3', dir: 'asc'}]
multiple_sort(items, options)
#=> [{:field1=>"1", :field2=>1, :field3=>3},
# {:field1=>"1", :field2=>5, :field3=>5},
# {:field1=>"3", :field2=>3, :field3=>2},
# {:field1=>"3", :field2=>1, :field3=>8},
# {:field1=>"7", :field2=>5, :field3=>1},
# {:field1=>"7", :field2=>5, :field3=>6}]
options = [{field: 'field1', dir: 'desc'}, {field: 'field3', dir: 'desc'}]
multiple_sort(items, options)
# => [{:field1=>"7", :field2=>5, :field3=>6},
# {:field1=>"7", :field2=>5, :field3=>1},
# {:field1=>"3", :field2=>1, :field3=>8},
# {:field1=>"3", :field2=>3, :field3=>2},
# {:field1=>"1", :field2=>5, :field3=>5},
# {:field1=>"1", :field2=>1, :field3=>3}]
items << {:field1=>"1", :field2=>6, :field3=>5}
#=> [{:field1=>"1", :field2=>5, :field3=>5},
# {:field1=>"1", :field2=>1, :field3=>3},
# {:field1=>"3", :field2=>3, :field3=>2},
# {:field1=>"3", :field2=>1, :field3=>8},
# {:field1=>"7", :field2=>5, :field3=>6},
# {:field1=>"7", :field2=>5, :field3=>1},
# {:field1=>"1", :field2=>6, :field3=>5}]
options = [{field: 'field1', dir: 'asc'}, {field: 'field3', dir: 'desc'},
{field: 'field2', dir: 'desc'}]
multiple_sort(items, options)
#=> [{:field1=>"1", :field2=>6, :field3=>5},
# {:field1=>"1", :field2=>5, :field3=>5},
# {:field1=>"1", :field2=>1, :field3=>3},
# {:field1=>"3", :field2=>1, :field3=>8},
# {:field1=>"3", :field2=>3, :field3=>2},
# {:field1=>"7", :field2=>5, :field3=>6},
# {:field1=>"7", :field2=>5, :field3=>1}]