【问题标题】:How do I loop through a string with an array of strings to find matches?如何遍历带有字符串数组的字符串以查找匹配项?
【发布时间】:2011-05-28 03:30:35
【问题描述】:

我正在尝试用一个字符串数组遍历一个标题字符串,并查看数组中的哪些匹配。

我的代码运行良好,但我不确定这是否是最有效的方法。

重要的是数组中的字符串不必与标题中的短语完全匹配。只要每个单词都在标题中,它们就可以按任何顺序排列。任何帮助都会很棒。

EX.title = "Apple Iphone 4 Verizon"
   array = ["iphone apple, verizon iphone", "iphone 3g", "iphone 4", "cool iphone"]

我需要它返回["iphone apple", "verizon iphone", "iphone 4"]。字符串“verizon iphone”和“iphone apple”中的单词在标题中,顺序无所谓

results = [] 

#Loop through all the pids to see if they are found in the title
all_pids = ["iphone 3gs", "iphone white 4", "iphone verizon", "black iphone", "at&t      iphone"]
title = "Apple Iphone 4 White Verizon"
all_pids.each do |pid|
    match = []
    split_id = pid.downcase.split(' ')
    split_id.each do |name|

      in_title = title.downcase.include?(name) 
      if in_title == true
        match << name
      end
    end

    final = match.join(" ")

    if final.strip == pid.strip
      results << pid
    end

end

print results

当我运行它时,它会打印出我需要的内容["iphone white 4", "iphone verizon"]

【问题讨论】:

    标签: ruby arrays loops


    【解决方案1】:

    您可以执行以下操作:

    >> require 'set'
    => true
    >> title = "Apple Iphone 4 Verizon"
    => "Apple Iphone 4 Verizon"
    >> all_pids = ["iphone apple", "verizon iphone", "iphone 3g", "iphone 4", "cool iphone"]
    => ["iphone apple", "verizon iphone", "iphone 3g", "iphone 4", "cool iphone"]
    >> title_set = Set.new(title.downcase.split)
    => #<Set: {"apple", "iphone", "4", "verizon"}>
    >> all_pids.select { |pid| Set.new(pid.downcase.split).subset? title_set }
    => ["iphone apple", "verizon iphone", "iphone 4"]
    

    您可以对数组差异做一些非常相似的事情,但集合可能会更快,因为它们是作为哈希实现的。

    【讨论】:

    • 我认为,这种与 Set 的替代方案更好更干净,没有使用不必要的辅助变量。
    • 很高兴听到! :-) 如果这是您正在寻找的答案,您应该接受它(计票旁边的勾号),以便其他人知道该问题已得到回答。
    【解决方案2】:

    在我看来,您希望找到由与标题中的字符串严格相交的字符串组成的字符串。

    Array#- 执行集差操作。 [2] - [1,2,3] = [][1,2,3] - [2] = [1,3]

    title = "Apple Iphone 4 White Verizon"
    all_pids = ["iphone 3gs", "iphone white 4", "iphone verizon", "black iphone", "at&t      iphone"]
    set_of_strings_in_title = title.downcase.split
    all_pids.find_all do |pid|
      set_of_strings_not_in_title = pid.downcase.split - set_of_strings_in_title 
      set_of_strings_not_in_title.empty?
    end
    

    编辑:将 #find 更改为 #find_all 以返回所有匹配项,而不仅仅是第一个。

    【讨论】:

    • 你的答案和我差不多,而且你比我快。我屈服于你的回答。
    • 对此我担心的一件事是它会随着all_pids 数组的增长而减慢。首先为all_pids 中的术语设置一些查找表可能会降低这种影响。
    • 由于某种原因,这只返回“iphone white 4”,它也应该返回“iphone verizon”
    • @blakecash 对不起,我的错:应该是“find_all”而不是“find”。我已经编辑了示例。
    猜你喜欢
    • 1970-01-01
    • 2015-04-08
    • 2015-07-29
    • 2014-06-25
    • 1970-01-01
    • 2017-04-22
    • 1970-01-01
    • 2019-05-27
    • 2022-10-14
    相关资源
    最近更新 更多