-1

我有这两个数组

ArrayA = ["exampl@gmail.com", "example@techsolutions.net", "test@topgear.com"]
ArrayB = ["TopGear","Gmail", "Tech Solutions", "Google", "Facebook", "Exxon"]

现在我想做的是,如果ArrayA包含 中存在的任何值ArrayB,它应该返回该值。我知道对于一个条目,我可以使用该include?方法。我也想过将一个数组循环到另一个数组中,但这似乎不对,会遇到错误数量的循环。

那么我如何在这里比较两个数组并返回值,ArrayB如果返回为真呢?

例如,比较何时ArrayAArrayB。数组中的输出可能看起来像

ArrayC = ["Gmail", "Tech Solutions", "TopGear"]

因为邮件中ArrayA的内容与ArrayB.

希望这是有道理的。

注意:数组中的元素数量不限于上例所示。将来数组中可以有更多这样的元素。

谢谢。任何帮助都是

4

4 回答 4

2
ArrayA = ["exampl@gmail.com", "example@techsolutions.net", "test@topgear.com"]
ArrayB = ["TopGear","Gmail", "Tech Solutions", "Google", "Facebook", "Exxon"]

Hash[ArrayA.map{|i| [i,ArrayB.find_all{|j| i.include? j.downcase }]}]
#>> {"exampl@gmail.com"=>["Gmail"], "example@techsolutions.net"=>[], "test@topgear.com"=>["TopGear"]}

编辑:

ArrayA = ["exampl@gmail.com", "example@techsolutions.net", "test@topgear.com"]
ArrayB = ["TopGear","Gmail", "Tech Solutions", "Google", "Facebook", "Exxon"]

ArrayA.flat_map{|i| ArrayB.find_all{|j| i.include? j.delete(" ").downcase } }.uniq
#>> ["Gmail", "Tech Solutions", "TopGear"]
于 2013-06-18T07:58:42.230 回答
2

找到交点的简单情况是:

ArrayA | ArrayB

根据您的示例查找匹配交叉点的朴素算法是:

ArrayA.select do |e|
  ArrayB.each_with_object( e.downcase )
    .reduce( false ) { |a, (e, o)| a or o.include? e.downcase }
end
# => ["exampl@gmail.com", "test@topgear.com"]; Tech Solutions hase space in it

使用后缀树可以实现更好的算法,但这只有在您的数组每个元素超过 1000 个时才有优势。这有点难以演示,因为很难找到适合后缀树的 Ruby gem。但出于演示目的,人们总是可以这样做git clone git://github.com/respan/ukkonen-ruby.git,然后cd进入目录,并在irb那里运行。然后:

require './ukkonen'
tree = SuffixTree.new ArrayA.join; nil
ArrayB.select { |e| tree.contains? e.downcase.delete ' ' }
#=>["TopGear", "Gmail", "Tech Solutions"]

请注意,虽然我的愿望为.ArrayAArrayA.join

于 2013-06-18T08:05:49.447 回答
1

循环两个数组是唯一的方法。这并不像存在一些可以在线性时间内比较两个数组的魔术函数。

看起来你想做的不仅仅是比较两个字符串。这并没有让它变得更容易。

于 2013-06-18T07:59:20.720 回答
1

如果电子邮件检查是关键问题,我认为这段代码会提供更好的性能(不需要嵌套循环),但这不是一个常见的解决方案。

Hash h = {}
ArrayB.each{|x| h[x.delete(" ").downcase] = 0}
ArrayA.each{|s|
    m = p(/.*@([^\.]+)\..*/).match(s);
    h[m[1]] += 1 if(m && h[m[1]]) 
}
ArrayC = [];
h.each{|k,v|  ArrayC << k if v > 0}
于 2013-06-18T08:30:46.533 回答