我正在尝试了解sort_by
方法。这是我正在尝试的脚本:
def test(x)
if x[:type] == 1
# move the hash to the first index of the array
end
end
values = [{value: "First", type: 0},{value: "Second", type: 1},{value: "1111", type: 0},{value: "2222", type: 1}]
values.sort_by! { |x| test(x) }
puts values
如何明确说明我希望将所选索引移动到的索引?我希望将类型为1的哈希值全部移动到前三个索引,并且它们的顺序不会更改。
答案 0 :(得分:0)
使用sort_by
执行您想要的操作(但如果两个元素返回相同的值但未显示sort_by的工作方式,则不保留原始顺序)
values.sort_by! { |x| x[:type] == 1 ? 0 : 1 }
# => [{:value=>"2222", :type=>1}, {:value=>"Second", :type=>1},
# {:value=>"1111", :type=>0}, {:value=>"First", :type=>0}]
sort_by
根据块返回的值按升序对元素进行排序。
在这种情况下,它遍历数组并将每个元素传递给下一个块x
{ |x| x[:type] == 1 ? 0 : 1 }
从上面的块返回的值相互比较并用于创建最终有序数组。
在这种情况下,如果0
则返回x[:type] == 1
,否则返回1
。因此,将首先排序x[:type] == 1
的所有元素。
查看有关sort_by
here
答案 1 :(得分:0)
要在此处使用sort_by
,您需要找到一种方法来保持顺序正确。这是一个,虽然它有点像黑客:
values = [{value: "First", type: 0}, {value: "Second", type: 1},
{value: "1111", type: 0}, {value: "2222", type: 1}]
type = 1
n = values.size # => 4
values.each_with_index {|h,i| h[:type] = i-n if h[:type] == type}
# => [{:value=>"First", :type=>0}, {:value=>"Second", :type=>-3},
{:value=>"1111", :type=>0}, {:value=>"2222", :type=>-1}]
values.sort_by! {|h| h[:type]}
# => [{:value=>"Second", :type=>-3}, {:value=>"2222", :type=>-1},
{:value=>"1111", :type=>0}, {:value=>"First", :type=>0}]
values.map {|h| h[:type] = type if h[:type] < 0; h}
# => [{:value=>"Second", :type=>1}, {:value=>"2222", :type=>1},
{:value=>"1111", :type=>0}, {:value=>"First", :type=>0}]
答案 2 :(得分:0)
values.sort_by {| X | X [:类型]}
干杯。
答案 3 :(得分:0)
使用#sort或#sort_by时,不能声明应移动项目的索引。但是,您可以指定顺序,让#sort_by完成剩下的工作。
第一个问题是sort_by不稳定:可以按任何顺序发出相等的项目。你需要一个稳定的排序,所以让我们的Monkey-patch Enumerable有一个#stable_sort_by方法:
module Enumerable
def stable_sort_by
map.each.with_index.sort_by do |e, i|
[yield(e), i]
end.map(&:first)
end
end
根据块返回的值进行排序,就像#sort_by一样,但如果值相等,则按项顺序排序。这保留了相等项目的相对顺序。
现在,使用新定义的#stable_sort_by:
values.sort_by! do |h|
if h[:type] == 1
0
else
1
end
end
这会将类型为1的所有项目移至开头,否则会保留项目的相对顺序。