Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Ruby 1.9中仅获取有序哈希的子集?_Ruby_Hash - Fatal编程技术网

如何在Ruby 1.9中仅获取有序哈希的子集?

如何在Ruby 1.9中仅获取有序哈希的子集?,ruby,hash,Ruby,Hash,让我们举一个例子: d = {"a" => 1, "b" => 2, "c" => 3, "d" => 4} 由于散列现在是有序的,所以我可能希望从a到b或从c到d获取数据。问题是我不能做d[0..1]或d[2..3] 不过,我可以: irb > d.to_a[0..1] => [["a", 1], ["b", 2]] 。。。但这感觉很混乱,我不想为这样的操作抛出我的散列 有没有更干净的解决方案来处理这个问题 # Holy Grail irb >

让我们举一个例子:

d = {"a" => 1, "b" => 2, "c" => 3, "d" => 4}
由于散列现在是有序的,所以我可能希望从a到b或从c到d获取数据。问题是我不能做d[0..1]或d[2..3]

不过,我可以:

irb > d.to_a[0..1]
=> [["a", 1], ["b", 2]] 
。。。但这感觉很混乱,我不想为这样的操作抛出我的散列

有没有更干净的解决方案来处理这个问题

# Holy Grail
irb > d[0..1]
=> {"a" => 1, "b" => 2}
我知道如何为自己编写这样一个方法,但可能有一些本机已经完成了,我可以使用…?

您可以这样做:

> a = {"a" => 1, "b" => 2, "c" => 3, "d" => 4}
> a.slice(*a.keys[0..1])
=> {"a" => 1, "b" => 1}

至少散列没有被强制转换,但在我看来它仍然不是很优雅。

如果您想对键进行比较以选择子集,您可以使用,它在1.8.7中也有效,但会返回一个数组数组,而不是按照您的示例

d.select {|k, v| k < 'c' } # => {"a"=>1, "b"=>2}
d.select {|k, v| k < 'c' } # 1.8.7 => [["a", 1], ["b", 2]]

也许有更好的方法,但这是一个想法:

class Hash
    def slice_by_index(a, b = nil)  
        k = if a.is_a?(Range)
            keys[a]
        elsif b.nil?
            [keys[a]]
        else
            keys[a,b]
        end
        k.inject({}){|h, k| h[k] = self[k] ; h }
    end
end

h = {"a" => 1, "b" => 2, "c" => 3, "d" => 4}
p h.slice_by_index(1..3) #range
p h.slice_by_index(2) #single element
p h.slice_by_index(0,3) #start, lenght

一个范围也可以是一个有效的散列键,因此您必须为此使用一个自定义方法。顺便说一句,我不认为有什么内置的。在这种情况下,OP需要一个Hashslice_by_索引,包含Array[]支持的所有选项。是的,大多数时候,你知道你想要的键或者如何根据比较来选择键,但他想要基于索引的键,这不是我回答的。最重要的是,我的答案很糟糕,因为它使用了ActiveSupport,只需要Hashvalues_at,正如@DuoSRX所示。@BiHi在我的情况下,我想根据它们的索引而不是它们的值来获取密钥。如果你简单地用某种修补到Hash上的方法将其包装起来,那会更加优雅。这是一种合理的方法,但是你仍然需要得到散列的所有密钥。但是,如果实现不支持按索引对哈希进行切片,则很难找到更好的方法。Hashvalues\u将如何返回哈希。它将仅作为数组返回键的值。看,我的错,你是对的。那么我想最好的解决方案是按照BiHi的建议使用hashslice,比如:a.slice*a­.keys[0..1­]您可以使用facets gem中的slice:include facets/hash/slice;a、 切片*a­键[0..1­]。无需加载导轨,也无需加载整个面。
class Hash
    def slice_by_index(a, b = nil)  
        k = if a.is_a?(Range)
            keys[a]
        elsif b.nil?
            [keys[a]]
        else
            keys[a,b]
        end
        k.inject({}){|h, k| h[k] = self[k] ; h }
    end
end

h = {"a" => 1, "b" => 2, "c" => 3, "d" => 4}
p h.slice_by_index(1..3) #range
p h.slice_by_index(2) #single element
p h.slice_by_index(0,3) #start, lenght