【问题标题】:Filter array of strings, including "like" condition过滤字符串数组,包括“like”条件
【发布时间】:2016-04-03 09:19:50
【问题描述】:

如果我的主数组是["Hello","Bye","Halo"],并且我正在搜索"lo",它将仅将数组过滤到["Hello", "Halo"]

这是我尝试过的:

 let matchingTerms = filter(catalogNames) {
        $0.rangeOfString(self.txtField.text!, options: .CaseInsensitiveSearch) !=  nil
    }

它抛出

Type of expression is ambiguous without more context

有什么建议吗?

【问题讨论】:

    标签: ios arrays swift string filter


    【解决方案1】:

    改用contains

    let arr = ["Hello","Bye","Halo"]
    let filtered = arr.filter { $0.contains("lo") }
    print(filtered)
    

    输出

    [“你好”,“光环”]

    感谢@user3441734 指出该功能当然只有在您import Foundation 时才可用

    【讨论】:

    • .. 别忘了 import Foundation
    • 太棒了,谢谢。在我可以投票之前给我几分钟时间
    • @user3441734 谢谢,你说得对——总是忘记导入,因为它们已经在项目中了。
    • 如何添加多个条件?例如let filters = arr.filter { $0.containsString("lo") OR $0.containsString("ll") } 会这样吗?
    • 你需要插入lowercased()以获得更好的结果
    【解决方案2】:

    在 Swift 3.0 中

    let terms = ["Hello","Bye","Halo"]
    
    var filterdTerms = [String]()
    
    
    func filterContentForSearchText(searchText: String) {
        filterdTerms = terms.filter { term in
            return term.lowercased().contains(searchText.lowercased())
        }
    }
    
    
    filterContentForSearchText(searchText: "Lo")
    print(filterdTerms)
    

    输出

    ["Hello", "Halo"]
    

    【讨论】:

    • 他要求快速的 two 语法。提供 swift3 答案有什么意义?
    • 当有人只搜索过滤字符串数组时,他/她会得到答案,并且可能会在升级版本中更新语法知识
    • 我认为它被要求用于 Swift 2,因为当时它是实际的,现在我们使用 Swift 3,所以它在这一刻更有价值。
    • @GhostCat 因为像我这样的人来自 Google 寻找 Swift 3 解决方案 :)
    • 这在操场上给了我错误“字符串”类型的值没有成员“包含”
    【解决方案3】:

    斯威夫特 3.1

    let catalogNames = [ "Hats", "Coats", "Trousers" ]
    let searchCatalogName = "Hats"
    
    let filteredCatalogNames = catalogNames.filter { catalogName in 
        return catalogName.localizedCaseInsensitiveContains(searchCatalogName)
    }
    
    print(filteredCatalogNames)
    

    【讨论】:

      【解决方案4】:

      我的尝试...

      let brands = ["Apple", "FB", "Google", "Microsoft", "Amazon"]
      
      let b = brands.filter{(x) -> Bool in 
      (x.lowercased().range(of: "A".lowercased()) != nil)
      }
      print(b) //["Apple", "Amazon"]
      

      【讨论】:

        【解决方案5】:

        借助 String 扩展,您可以使用纯 Swift 解决方案(无需 import Foundation)。我没有检查速度,但它应该不会比基础等效的更差。

        extension String {
            func contains(string: String)->Bool {
                guard !self.isEmpty else {
                    return false
                }
                var s = self.characters.map{ $0 }
                let c = string.characters.map{ $0 }
                repeat {
                    if s.startsWith(c){
                        return true
                    } else {
                        s.removeFirst()
                    }
                } while s.count > c.count - 1
                return false
            }
        }
        
        let arr = ["Hello","Bye","Halo"]
        let filtered = arr.filter { $0.contains("lo") }
        
        print(filtered) // ["Hello", "Halo"]
        
        "a".contains("alphabet") // false
        "alphabet".contains("")  // true
        

        【讨论】:

          【解决方案6】:

          您还需要与 NSNotFound 进行比较。 rangeOfString:options: 的文档说:

          一个 NSRange 结构,给出第一次出现的 aString 在接收器中的位置和长度,以掩码中的选项为模。如果 aString 未找到或为空 (@""),则返回 {NSNotFound, 0}。

          import Foundation
          
          let catalogNames = [ "Hats", "Coats", "Trousers" ]
          
          let matchingTerms = catalogNames.filter {
            $0.rangeOfString(self.txtField.text!, options: .CaseInsensitiveSearch).location != NSNotFound
          }
          

          【讨论】:

            【解决方案7】:

            Swift 5
            考虑下面的例子。从数组 1 中过滤(不区分大小写)数据并用它填充第二个数组

            let data = ["Apple", "Oranges", "Banana", "Grapes"]
            var filteredData = [String]()
            
            func filterText(_ text: String?) {
                guard let text = text else {return}
                
                filteredData.removeAll()
                for element in data {
                    if element.lowercased().starts(with: text.lowercased()){
                        filteredData.append(element)
                    }
                }
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2021-03-16
              • 1970-01-01
              • 2017-07-15
              • 2021-01-27
              • 1970-01-01
              • 2022-07-04
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多