1

我试图理解这种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 的哈希全部移至前三个索引,并且它们的顺序不变。

4

4 回答 4

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 }

从上述块返回的值相互比较并用于创建最终的有序数组。

在这种情况下,返回的值是0ifx[:type] == 11else。所以所有元素x[:type] == 1都将首先排序。

在此处查看更多信息sort_by

于 2013-10-09T23:16:54.137 回答
0

values.sort_by{|x| x[:类型]}

干杯。

于 2013-10-10T04:37:42.850 回答
0

在使用#sort 或#sort_by 时,您不能声明项目应移动到的索引。但是,您可以指定顺序并让#sort_by 完成其余的工作。

第一个问题是 sort_by 不稳定:相等的项目可以以任何顺序发出。你需要一个稳定的排序,所以让我们猴子补丁 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的项目移到开头,但否则项目的相对顺序保持不变。

于 2014-02-11T16:53:21.340 回答
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}] 
于 2013-10-10T04:21:28.167 回答