Ruby:哈希数组 - 如何根据作为数组的哈希键删除重复项

时间:2016-09-15 18:03:52

标签: arrays ruby hash

我有一个哈希数组,其中每个哈希的键是包含2个整数的数组 - 看起来像这样:

  [{[6, 8]=>0.5932190854209105}, {[6, 13]=>0.7183325285691291}, {[6, 15]=>0.8253727388780498}, {[8, 6]=>0.5932190854209105}, {[8, 13]=>0.7255537819950661}, {[8, 15]=>0.5249232568337963}, {[13, 6]=>0.7183325285691291}, {[13, 8]=>0.7255537819950661}, {[13, 15]=>0.6348636166265346}, {[15, 6]=>0.8253727388780497}, {[15, 8]=>0.5249232568337963}, {[15, 13]=>0.6348636166265343}]

我需要删除重复项 - 在这种情况下,副本被定义为其键已经存在的哈希(但是以相反的顺序)。例如[6,15]和[15,6]。您可以看到,基于此定义,其中一半是重复的。

添加到此:

这由以下

组成
 @user_array.each do |u|
   @result << @user_array.map { |p| Hash[[u, p] => kappa(u, p, "ipf")] if p !=u  }
 end

user_array是一个整数数组(用户ID)。例如:

  [6, 8, 13, 15]

我需要在每个unorder配对组合上运行kappa助手。我似乎可以找出如何防止它&#34;倍增&#34;。我想我是否可以以某种方式保存这对,然后我可以进行比较。我知道如何做到这一点的唯一方法是使用哈希。我很新。

编辑:我试过这样的事情:

@user_array.each do |u|
   @result << @user_array.map { |p| Hash[[u, p].sort => kappa(u, p, "ipf")] if p !=u  }
end

但它们是离散的哈希......所以它不起作用:

 [{[6, 8]=>0.5932190854209105}, {[6, 13]=>0.7183325285691291}, {[6, 15]=>0.8253727388780498}, {[6, 8]=>0.5932190854209105}, {[8, 13]=>0.7255537819950661}, {[8, 15]=>0.5249232568337963}, {[6, 13]=>0.7183325285691291}, {[8, 13]=>0.7255537819950661}, {[13, 15]=>0.6348636166265346}, {[6, 15]=>0.8253727388780497}, {[8, 15]=>0.5249232568337963}, {[13, 15]=>0.6348636166265343}]

不是那么简单。

3 个答案:

答案 0 :(得分:3)

只要您的kappa函数为u,p生成与p,u相同的值,就可以执行此操作:

@result = @user_array.each_with_object({ }) do |u, h|
  @user_array.each do |p|
    next if (u == p)

    h[[u, p].sort] ||= kappa(u, p, "ipf")
  end
end

只填充一次和一次值。如果您想在最后一个值的位置进行操作,请将||=更改为=

答案 1 :(得分:2)

如果您对数组进行排序,似乎可以在传递中关闭此功能。由于您声明对的任何排列都是等价的,因此插入前的排序将允许散列消除/覆盖任何重复值。

@user_array.each do |u|
   @result << @user_array.map { |p| Hash[[u, p].sort => kappa(u, p, "ipf")] if p !=u  }
 end

答案 2 :(得分:0)

在评论中,OP已经阐明如果要保留数组的元素(哈希),并且该哈希的(唯一)键是[a,b],则没有后续哈希键{{1} }或[a,b]将被保留。

[b,a]表示您的哈希数组,每个哈希都有一个键/值对。

您可以使用Enumerable#uniqEnumerable#uniq,具体取决于是否要对arr进行修改。

arr

或者,要修改arr.uniq { |h| h.first.first.sort } #=> [{[6, 8]=>0.5932190854209105}, {[6, 13]=>0.7183325285691291}, # {[6, 15]=>0.8253727388780498}, {[8, 13]=>0.7255537819950661}, # {[8, 15]=>0.5249232568337963}, {[13, 15]=>0.6348636166265346}]

arr
如果arr.uniq! { |h| h.first.first.sort } || arr #=> [{[6, 8]=>0.5932190854209105}, {[6, 13]=>0.7183325285691291}, # {[6, 15]=>0.8253727388780498}, {[8, 13]=>0.7255537819950661}, # {[8, 15]=>0.5249232568337963}, {[13, 15]=>0.6348636166265346}] arr #=> [{[6, 8]=>0.5932190854209105}, {[6, 13]=>0.7183325285691291}, # {[6, 15]=>0.8253727388780498}, {[8, 13]=>0.7255537819950661}, # {[8, 15]=>0.5249232568337963}, {[13, 15]=>0.6348636166265346}] 不包含重复项,则需要

|| arr,在这种情况下,arr会返回uniq!

你也可以写

nil

(或require 'set' arr.uniq { |h| h.first.first.to_set } )。

引用uniq!的文档,&#34; uniq按顺序遍历,第一次出现。&#34;