在哈希数组中,如何编辑特定的哈希索引?

时间:2013-10-09 23:02:50

标签: ruby

我正在尝试了解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 个答案:

答案 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的所有项目移至开头,否则会保留项目的相对顺序。