【问题标题】:Efficiently Search Through Array in Swift在 Swift 中有效地搜索数组
【发布时间】:2015-03-26 12:23:56
【问题描述】:

我有一大堆 PFObject:giantRestaurantArray。我想检查每个数组对象"FoodType" 是否包含checkFoodOptionsArray 中的任何食物类型。如果找到食物类型,则将食物类型添加到foundFoodTypes 数组中。

循环效率低下,因为它一遍又一遍地检查数组(即使已经找到了食物类型)。如何提高搜索性能并跳过已添加的 FoodTypes

 var checkFoodOptionsArray = ["American", "BBQ", "Breakfast", "Buffet", "Burgers", "Cafe", "Wings", "Chinese", "Dessert", "FastFood", "Indian", "Italian", "Japanese", "Korean", "Pizza", "Sandwiches", "Seafood", "Steakhouse", "Thai", "Mexican", "Vietnamese", "Vegan", "OtherEthnic"]

 for items in checkFoodOptionsArray { checkIfFoodTypeOptionAvailable(items) }

 func checkIfFoodTypeOptionAvailable(optionValue: String){
    let isAvailable = contains(giantRestaurantArray as [PFObject]) { (object) -> Bool in
        if let type = object["FoodType"] as? String {
            return type.rangeOfString(optionValue) != nil
        }
        else {
            return false
        }
    }
    if isAvailable == true {
        foundFoodTypes.append(optionValue)
    } else {
        println("No, array does not contain \(optionValue)")
    }
}

【问题讨论】:

    标签: arrays performance sorting search swift


    【解决方案1】:

    您可以仅构建 DictionaryFoodTypes。构建可能有点贵,但查找基本上是免费的:

    // create lookup dictionary
    let foodTypes: [String: ()] = reduce(giantRestaurantArray as [PFObject], [:]) {
        (var result, object) in
        if let type = object["FoodType"] as? String {
            result[type] = ()
        }
        return result
    }
    
    // build list of un-matched foods:
    let foundFoodTypes: [String] = checkFoodOptionsArray.filter {
        foodTypes[$0] != nil 
    }
    

    【讨论】:

    • 感谢您的建议,我没想过为此构建一个字典。你认为这会比@fred02138 的回答更快吗?
    • 该答案等同于您当前的代码。与这个的性能差异可能取决于你的数组有多大——创建字典有点慢,但这样你只需要遍历你的巨型数组一次,所以如果它真的很大,你可以看到一些真实的这种方法的效率。理想情况下,您只需在应用程序的每个生命周期执行一次。
    • 谢谢内特。如果我想对giantRestaurantArray 应用相同的搜索但使用不同的object["PriceType"] 和选项数组,我是否需要构建另一个字典。或者我可以在不大幅增加费用的情况下将其添加到当前字典中吗?
    • 你需要另一本字典,因为字典只能有一个键。您仍然可以一次性构建它,您可能只是想以一种比答案中的功能性更强的风格(即for item in array { add to dictionaries })来完成它。
    【解决方案2】:

    我认为您只想在找到该项目后立即终止搜索,因此不要使用contains

    func checkIfFoodTypeOptionAvailable(optionValue: String){
        let isAvailable = false
    
        for obj in giantRestaurantArray {
            if let object = obj as? PFObject {
                if let type = object["FoodType"] as? String {
                    isAvailable = type.rangeOfString(optionValue) != nil
                    if isAvailable {
                        break
                    }
                }
            }
        }
    
    
        if isAvailable == true {
            foundFoodTypes.append(optionValue)
        } else {
            println("No, array does not contain \(optionValue)")
        }
    }
    

    【讨论】:

    • contains 已经有这种行为——在返回 true 后不再计算谓词。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-09
    • 2014-09-28
    • 2014-04-28
    • 1970-01-01
    • 1970-01-01
    • 2021-10-08
    相关资源
    最近更新 更多