Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.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中的哈希数组中获取唯一元素?_Ruby_Arrays_Hash_Unique - Fatal编程技术网

如何从Ruby中的哈希数组中获取唯一元素?

如何从Ruby中的哈希数组中获取唯一元素?,ruby,arrays,hash,unique,Ruby,Arrays,Hash,Unique,我有一个散列数组,我想从中得到唯一的值。调用Array.uniq并不能满足我的期望 a = [{:a => 1},{:a => 2}, {:a => 1}] a.uniq # => [{:a => 1}, {:a => 2}, {:a => 1}] 我期望的是: [{:a => 1}, {:a => 2}] [{:a=>1}, {:a=>2}, {:a=>1}].uniq #=> [{:a=>1}, {:a=

我有一个散列数组,我想从中得到唯一的值。调用
Array.uniq
并不能满足我的期望

a = [{:a => 1},{:a => 2}, {:a => 1}]
a.uniq # => [{:a => 1}, {:a => 2}, {:a => 1}]
我期望的是:

[{:a => 1}, {:a => 2}]
[{:a=>1}, {:a=>2}, {:a=>1}].uniq
#=> [{:a=>1}, {:a=>2}] 
在网上搜索时,我没有找到一个我满意的解决方案。人们建议重新定义
Hash.eql?
Hash.Hash
,因为这就是
Array.uniq
查询的内容

编辑: 当我在现实世界中遇到这个问题时,哈希稍微复杂一些。它们是经过解析的JSON的结果,JSON有多个字段,其中一些值也是哈希值。我有一个结果数组,我想过滤掉唯一的值

我不喜欢重定义
Hash.eql?
Hash.Hash
解决方案,因为我必须全局重定义
Hash
,或者为数组中的每个条目重定义它。更改每个条目的
Hash
的定义会很麻烦,特别是因为每个条目内部可能有嵌套的Hash

全局更改
Hash
有一定的潜力,尤其是临时更改时。我想构建另一个类或帮助函数来保存旧的定义并恢复它们,但我认为这增加了比实际需要更多的复杂性


使用
inject
似乎是重新定义
Hash

的一个很好的替代方法,我可以通过调用
inject

a = [{:a => 1},{:a => 2}, {:a => 1}]
a.inject([]) { |result,h| result << h unless result.include?(h); result }

你给出的答案与讨论的答案相似。它覆盖将在数组中显示的哈希上的
hash
eql?
方法,从而使
uniq
正常工作。

假设哈希始终是单键值对,这将起作用:

a.map {|h| h.to_a[0]}.uniq.map {|k,v| {k => v}}
to_a创建一个键值数组数组,因此第一个映射将获得:

[[:a, 1], [:a, 2], [:a, 1]]
阵列上的uniq满足您的需求,为您提供:

[[:a, 1], [:a, 2]]
然后,第二个映射将它们重新组合为散列。

可在谷歌上找到

我也遇到过类似的情况,但哈希有键。我用了分类法

我的意思是:

您有一个数组:

[{:x=>1},{:x=>2},{:x=>3},{:x=>2},{:x=>1}]
您对它进行排序(
#按{t | t[:x]}对u进行排序
)并得到以下结果:

[{:x=>1}, {:x=>1}, {:x=>2}, {:x=>2}, {:x=>3}]
现在是Aaron Hinni对答案的一点修改版本:

your_array.inject([]) do |result,item| 
  result << item if !result.last||result.last[:x]!=item[:x]
  result
end

Ruby 1.8.7+将返回您所期望的结果:

[{:a => 1}, {:a => 2}]
[{:a=>1}, {:a=>2}, {:a=>1}].uniq
#=> [{:a=>1}, {:a=>2}] 
数组上的管道方法(从1.8.6开始提供)执行集合并集(返回数组),因此以下是获取任何数组的唯一元素的另一种可能方法
a

[]| a

您可以使用(在ruby 1.9.3中测试)


我遇到的现实问题使用了更复杂的哈希,这是我在网上找到的解决方案之一。我不喜欢,我需要重新定义哈希,只需要调用UNIQ。如果香草散列和数组类不做你需要的,你应该真正考虑定义自己的类来实现所需的行为。你能描述一下你试图用散列数组建模的是什么吗?我认为比我发布的一个链接要好得多above@SunnyRGupta,您使用的是什么版本的Ruby?
Ruby 1.9.3p448(2013-06-27修订版41675)[x86\u 64-darwin13.2.0]
@SunnyRGupta,我不知道该说什么。我刚刚又做了一次测试,效果非常好IRB1.9.3p448:001>a=[{:a=>1},{:a=>2},{:a=>1}=>[{:a=>1},{:a=>2},{:a=>1}]1.9.3p448:002>[}a=>[{:a=>1},{:a=>2}]
Rehearsal ---------------------------------------------
sorting:    0.010000   0.000000   0.010000 (  0.005633)
inject:     0.470000   0.140000   0.610000 (  0.621973)
------------------------------------ total: 0.620000sec

                user     system      total        real
sorting:    0.010000   0.000000   0.010000 (  0.003839)
inject:     0.480000   0.130000   0.610000 (  0.612438)
[{:a=>1}, {:a=>2}, {:a=>1}].uniq
#=> [{:a=>1}, {:a=>2}] 
[{a: 1},{a: 2},{a:1}].uniq => [{a:1},{a: 2}]
[{a: 1,b: 2},{a: 2, b: 2},{a: 1, b: 3}].uniq_by {|v| v[:a]} => [{a: 1,b: 2},{a: 2, b: 2}]