繁体   English   中英

在 Swift 中对 searchBar 结果进行过滤和排序

[英]Filter and sort array for searchBar result in Swift

我正在尝试对我的项目进行搜索。 我需要过滤变量productTagsArray并填充数组allProductSearchResults searchText是用户在 searchBar 中键入的内容。 这是我必须过滤的代码:

var allProductSearchResults: [[String : [String]]] = [[:]]
var productTagsArray : [[String : [String]]] = [[:]]

func filterContent(for SearchText: String){

allProductSearchResults = productTagsArray.filter({ (productTagsArray) -> Bool in
        for product in productTagsArray {
            if let tags = product.value as? [String] {

                for tag in tags {

                    let searchTextArr = SearchText.split {$0 == " "}
                    let searchX = searchTextArr.flatMap { $0.lowercased().components(separatedBy: " ")}
                    let tagLowerCase = tag.lowercased().replacingOccurrences(of: ",", with: " ")
                    let isMatch = searchX.filter { tagLowerCase.range(of:$0) != nil }.count != 0
                    return isMatch

                }
            }

            return false
        }
        return false
    })
}

上面的代码工作得很好; 但是,变量allProductSearchResults的最终结果未排序。 我需要根据tagsearchText之间匹配的单词数对结果进行排序。 例如,如果有人搜索organic green kale

searchText = "organic green kale"

如果我有以下产品,则在 productTagsArray 中:

productTagsArray = [["product1" : [kale]], ["product2" : [organic green kale, organic, green, kale]], ["product3" : [organic cucumber, organic, cucumber]]]

使用上面的代码完成过滤器后,我想确保它是根据 searchText 和标签之间的匹配进行排序的,因此它会按以下顺序排列:

allProductSearchResults = [["product2" : [organic green kale, organic, green, kale]], ["product1" : [organic kale, organic, kale]], ["product3" : [organic cucumber, organic, cucumber]]]

如何使这种排序成为可能?

而不是过滤,它只删除不匹配的产品,想法是首先将map放入一个元组中,计算匹配的数量和产品旁边,然后filter掉那些匹配为 0 的产品,排序,然后map回到产品中.

func filterContent(for searchText: String) -> [[String : [String]]] {
   let searchTokens = searchText.split(" ")

   return productTagsArray.map { productTags -> ([String: [String]], Int) in
       
      var matches = 0
      for (_, tags) in productTags {

         for searchToken in searchTokens {

            // sum up the matches that of this search token 
            matches += tags.reduce(0, { 
               $0 + ($1.localizedCaseInsensitiveContains(searchToken) ? 1 : 0) })
         }

      }

      return (productTags, matches) // <-- return product with # of matches
   }
   .filter({ $0.1 > 0 }) // <-- filter out zero matches
   .sorted(by: { $0.1 > $1.1 }) // <-- sort by matches
   .map { $0.0 } // <-- map back to productTags

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM