按类别名称对数组进行排序
Sorting an array by category names
给定这个数组 a
:
a = [
{id: 3, category_name: "Horror"},
{id: 4, category_name: "Non-Fiction"},
{id: 5, category_name: "LGBT"},
{id: 6, category_name: "Romance"},
{id: 7, category_name: "Romance"}
]
我想要一种使用数组顺序(索引)按类别名称对数组 a
中的对象进行排序的方法,幸运的是 Ruby 数组默认是有序数组:
categories_sorted = [
"Romance",
"LGBT",
"Non-Fiction",
"Horror"
]
这样排序算法就会给我一个如下所示的数组:
result = [
{id: 6, category_name: "Romance"},
{id: 7, category_name: "Romance"},
{id: 5, category_name: "LGBT"},
{id: 4, category_name: "Non-Fiction"},
{id: 3, category_name: "Horror"}
]
您能指出有效实现此目标的任何方法吗?
数组 "a" 可以大到 20 个对象,而排序的类别在我的场景中可以有多达 30 个类别。
做如下:-
a = [
{id: 3, category_name: "Horror"},
{id: 4, category_name: "Non-Fiction"},
{id: 5, category_name: "LGBT"},
{id: 6, category_name: "Romance"},
{id: 7, category_name: "Romance"}
]
categories_sorted = [
"Romance",
"LGBT",
"Non-Fiction",
"Horror"
]
p a.sort_by { |h| [categories_sorted.index(h[:category_name]), h[:id]] }
# >> [{:id=>6, :category_name=>"Romance"}, {:id=>7, :category_name=>"Romance"}, {:id=>5, :category_name=>"LGBT"}, {:id=>4, :category_name=>"Non-Fiction"}, {:id=>3, :category_name=>"Horror"}]
值得编制一个排序索引列表以避免必须不断查找:
categories_sorted_index = Hash[
categories_sorted.each_with_index.collect do |name, index|
[ name, index ]
end
]
a.sort_by do |entry|
categories_sorted_index[entry[:category_name]] || 0
end
# =>
# {:id=>7, :category_name=>"Romance"}
# {:id=>6, :category_name=>"Romance"}
# {:id=>5, :category_name=>"LGBT"}
# {:id=>4, :category_name=>"Non-Fiction"}
# {:id=>3, :category_name=>"Horror"}
这里有一个使用Enumerable#group_by and Hash#values_at rather than Enumerable#sort_by的方法:
a.group_by { |h| h[:category_name] }.values_at(*categories_sorted).flatten
#=> [{:id=>6, :category_name=>"Romance"},
# {:id=>7, :category_name=>"Romance"},
# {:id=>5, :category_name=>"LGBT"},
# {:id=>4, :category_name=>"Non-Fiction"},
# {:id=>3, :category_name=>"Horror"}]
给定这个数组 a
:
a = [
{id: 3, category_name: "Horror"},
{id: 4, category_name: "Non-Fiction"},
{id: 5, category_name: "LGBT"},
{id: 6, category_name: "Romance"},
{id: 7, category_name: "Romance"}
]
我想要一种使用数组顺序(索引)按类别名称对数组 a
中的对象进行排序的方法,幸运的是 Ruby 数组默认是有序数组:
categories_sorted = [
"Romance",
"LGBT",
"Non-Fiction",
"Horror"
]
这样排序算法就会给我一个如下所示的数组:
result = [
{id: 6, category_name: "Romance"},
{id: 7, category_name: "Romance"},
{id: 5, category_name: "LGBT"},
{id: 4, category_name: "Non-Fiction"},
{id: 3, category_name: "Horror"}
]
您能指出有效实现此目标的任何方法吗? 数组 "a" 可以大到 20 个对象,而排序的类别在我的场景中可以有多达 30 个类别。
做如下:-
a = [
{id: 3, category_name: "Horror"},
{id: 4, category_name: "Non-Fiction"},
{id: 5, category_name: "LGBT"},
{id: 6, category_name: "Romance"},
{id: 7, category_name: "Romance"}
]
categories_sorted = [
"Romance",
"LGBT",
"Non-Fiction",
"Horror"
]
p a.sort_by { |h| [categories_sorted.index(h[:category_name]), h[:id]] }
# >> [{:id=>6, :category_name=>"Romance"}, {:id=>7, :category_name=>"Romance"}, {:id=>5, :category_name=>"LGBT"}, {:id=>4, :category_name=>"Non-Fiction"}, {:id=>3, :category_name=>"Horror"}]
值得编制一个排序索引列表以避免必须不断查找:
categories_sorted_index = Hash[
categories_sorted.each_with_index.collect do |name, index|
[ name, index ]
end
]
a.sort_by do |entry|
categories_sorted_index[entry[:category_name]] || 0
end
# =>
# {:id=>7, :category_name=>"Romance"}
# {:id=>6, :category_name=>"Romance"}
# {:id=>5, :category_name=>"LGBT"}
# {:id=>4, :category_name=>"Non-Fiction"}
# {:id=>3, :category_name=>"Horror"}
这里有一个使用Enumerable#group_by and Hash#values_at rather than Enumerable#sort_by的方法:
a.group_by { |h| h[:category_name] }.values_at(*categories_sorted).flatten
#=> [{:id=>6, :category_name=>"Romance"},
# {:id=>7, :category_name=>"Romance"},
# {:id=>5, :category_name=>"LGBT"},
# {:id=>4, :category_name=>"Non-Fiction"},
# {:id=>3, :category_name=>"Horror"}]