我有一个id数组,顺序是
order = [5,2,8,6]
和另一个哈希数组
[{id: 2,name: name2},{id: 5,name: name5}, {id: 6,name: name6}, {id: 8,name: name8}]
我想把它排序为
[{id: 5,name: name5},{id: 2,name: name2}, {id: 8,name: name8}, {id: 6,name: name6}]
实现这一点的最佳方法是什么?我可以实现这与迭代和推到新的数组,但寻找更好的解决方案。
试试这个
arr = [
{:id=>2, :name=>"name2"}, {:id=>5, :name=>"name5"},
{:id=>6, :name=>"name6"}, {:id=>8, :name=>"name8"}
]
order = [5,2,8,6]
arr.sort_by { |a| order.index(a[:id]) }
# => [{:id=>5, :name=>"name5"}, {:id=>2, :name=>"name2"},
#{:id=>8, :name=>"name8"}, {:id=>6, :name=>"name6"}]
Enumerable#in_order_of (Rails 7+)
从Rails 7开始,有一个新方法Enumerable#in_order_of.
引用自Rails官方文档:
in_order_of(关键系列)
根据原可枚举对象的
key
,返回一个新的Array
,其中顺序已设置为series
中提供的顺序。
[ Person.find(5), Person.find(3), Person.find(1) ].in_order_of(:id, [ 1, 5, 3 ])
=> [ Person.find(1), Person.find(5), Person.find(3) ]
如果
series
包含在Enumerable
中没有相应元素的键,则忽略这些键。如果Enumerable
有series
中没有命名的附加元素,这些元素将不包含在结果中。
在哈希的情况下并不完美,但您可以考虑这样做:
require 'ostruct'
items = [{ id: 2, name: 'name2' }, { id: 5, name: 'name5' }, { id: 6, name: 'name6' }, { id: 8, name: 'name8' }]
items.map(&OpenStruct.method(:new)).in_order_of(:id, [5,2,8,6]).map(&:to_h)
# => [{:id=>5, :name=>"name5"}, {:id=>2, :name=>"name2"}, {:id=>8, :name=>"name8"}, {:id=>6, :name=>"name6"}]
来源:
- 官方文档-可枚举#in_order_of.
- PR - Enumerable#in_order_of #41333.
- Rails 7添加Enumerable#in_order_of.