我想减去两个二维数组,可以选择将注意力放在“唯一 ID”列上。
也很好奇一种更能描述我正在寻找的内容的方式。
但是,例如,给定两个数组:
big = [['foo','bar@','baz'],
['cat','moew@','purr'],
['dog','bark@','woof'],
['mew', 'two@', 'blue']]
little = [['foo','bar@','baz'],
['dog','moew@','woof'],
['dog','bark@','woof']]
然后我们可以减去它们:
big - little #=> [["cat", "moew@", "purr"], ["mew", "two@", "blue"]]
这是有效的,因为 ['cat','moew@','purr'] != ['dog','moew@','woof']
。但是,我希望这两个被视为相等,因为它们在“唯一 ID”列中具有相同的值。
我是这样解决的:
big = [['foo','bar@','baz'],
['cat','moew@','purr'],
['dog','bark@','woof'],
['mew', 'two@', 'blue']]
little = [['foo','bar@','baz'],
['dog','moew@','woof'],
['dog','bark@','woof']]
def subtract big, little, key_index=nil
return big - little unless key_index
little_keys = little.map { |row| row[key_index] }.flatten
big.inject([]) do |result, row|
result << row unless little_keys.grep(row[key_index]).any?
result
end
end
subtract(big,little) #=> [["cat", "moew@", "purr"], ["mew", "two@", "blue"]]
subtract(big, little, 1) #=> [["mew", "two@", "blue"]]
很想知道更多关于如何描述我正在尝试做的事情以及是否有更好的方法。
此外,我的方法是 O(n^2)
因为它遍历整个数组两次吗?一次用于 #inject
一次用于 #grep
?
最佳答案
big = [['foo','bar@','baz'],
['cat','moew@','purr'],
['dog','bark@','woof'],
['mew', 'two@', 'blue']]
little = [['foo','bar@','baz'],
['foo','bark@','baz'],
['dog','moew@','woof'],
['dog','bark@','woof']]
请注意,我已经从问题中的示例中更改了 little
。
require 'set'
little_set = little.each_with_object(Set.new) { |(_,u,_), set| set << u }
#=> #<Set: {"bar@", "bark@", "moew@"}>
big.reject { |_,m,_| little_set.include?(m) }
#=> [["mew", "two@", "blue"]]
关于arrays - 使用唯一 id 列减去 2 维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41781856/