Ruby减去两个字符串数组

时间:2018-02-09 22:58:27

标签: arrays ruby

array1 = ["NORTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST", "SOUTH"]
array2 = ["NORTH", "SOUTH", "EAST", "WEST"]

“减去”两个数组,结果是:

["NORTH", "WEST", "SOUTH"]

字符串的顺序无关紧要。元素的位置无关紧要。这是另一个例子:

array1 = ["Hi", "Jimmy", "Whats", "Up"]
array2 = ["Whats", "Hi"]
SOME CODE
result = ["Jimmy", "Up"] 

另一个例子:

array1 = ['a','a','b','b','c']
array2 = ['a','c']
SOME CODE
result = ['a','b','b']

3 个答案:

答案 0 :(得分:2)

使用array1 - array2减去2个数组将删除array1中与array2中的值匹配的每个值。在你的情况下,那不是你想要的。

因此,您可以将自定义subtract()方法添加到Array类,如下所示:

class Array
  def subtract(array)
    array.each do |val|
      if index = index(val)
        delete_at(index)
      end
    end
  end
end

您可以像这样使用该方法:

array1 = ["NORTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST", "SOUTH"]
array2 = ["NORTH", "SOUTH", "EAST", "WEST"]
array1.subtract(array2)
puts(array1) # array1 now contains ["NORTH", "WEST", "SOUTH"]

答案 1 :(得分:1)

如果您希望使用集合

,这是一个不太复杂,更易读的解决方案
require 'set'
    class Array
      def minus(values)
        values_set = Set.new values 
        reject { |e| values_set.delete(e) if values_set.include?(e) }
      end
    end

用法:

array1 = ['a','a','b','b','c']
array2 = ['a','c']
puts array1.minus(array2)

编辑: 增强@ Ronan的解决方案,处理@Cary提到的案例

a = ["Hi", "Jimmy", "Whats", "Up"]
b = ["Whats", "Hi"]
c = b.each.with_object(a) { |del| a.delete_at(a.index(del))}
puts c

答案 2 :(得分:0)

这类似于@ Ronan的答案,但它不会改变array1

array1.difference(array2)
  #=> ["NORTH", "WEST", "SOUTH"]

['a','a','b','b','c'].difference(['a','c','d']
  #=> ["a", "b", "b"]

,其中

class Array
  def difference(other)
    h = other.each_with_object(Hash.new(0)) { |e,h| h[e] += 1 }
    reject { |e| h[e] > 0 && h[e] -= 1 }
  end
end

由于哈希查找几乎保持不变,因此该方法的计算复杂度接近于O([array1.size, array2.size].max)。

我建议将此方法添加到Ruby Core here中,但这样做几乎没有兴趣。该链接讨论了该方法的一些用途。