在定义键之前可以删除散列中的项目吗?例如:
hash = {
:foo => {"name" => "foo"},
:bar => {"name" => "bar"},
:baz => {"name" => "baz"}
}
# ToDo: remove items before :bar
result = {
:bar => {"name" => "bar"},
:baz => {"name" => "baz"}
}
我该怎么做?
答案 0 :(得分:4)
Ruby Hashes实际上并不是被设计为被视为有序集合,因此这并不像您期望的那样简单。但它们确实维护了关键的插入顺序,至少从Ruby 1.9开始,所以它是可能的。
这是一种方式;可能有更好的:
hash.delete(*hash.keys.each_with_index.find do |k, n|
n < hash.keys.each_with_index.select{|k,n| k==:bar}[1]
end.map(&:first))
首先,我们向哈希询问带有.keys
的密钥,它返回一个数组。然后我们在该数组上调用each_with_index
以将每个项目与数字索引相关联,所以现在我们迭代对(键,索引)。我们使用.find
搜索我们想要的密钥(k == :bar
),并使用[1]
获取其索引编号。
然后我们重新开始并使用.select
搜索相同的(密钥,索引)对列表,以查找索引 less 的所有密钥,而不是:bar
的索引。这次我们想要键而不是索引,所以我们通过.first
ping它们对每个对上调用map
。
使用我们想要删除的键数组;我们使用*
运算符将它们转换为参数列表,并将它们传递给Hash上的.delete
以实际删除它们。
答案 1 :(得分:3)
以下是一种方法:
hash.to_a.drop_while { |k, _| k != :bar }.to_h
正如马克指出的那样,旧版本的Ruby
Hash[*hash.to_a.drop_while { |k, _| k != :bar }]
答案 2 :(得分:1)
您可以使用Ruby使用不多的flip-flop operator。
hash = {
:foo => {"name" => "foo"},
:bar => {"name" => "bar"},
:baz => {"name" => "baz"},
:qux => {"name" => "qux"}
}
key = :baz
hash.select { |k,_| k==key..nil ? true : false }
#=> {:baz=>{"name"=>"baz"}, :qux=>{"name"=>"qux"}}
第二种方式如下。
ndx = hash.keys.index(key)
#=> 2
arr = [*[false]*ndx, *[true]*(hash.size-ndx)]
#=> [false, false, true, true]
hash.select { arr.shift }
#=> {:baz=>{"name"=>"baz"}, :qux=>{"name"=>"qux"}}