【问题标题】:Searching and Editing Values in Swift Array or Dictionary在 Swift 数组或字典中搜索和编辑值
【发布时间】:2022-11-20 18:48:41
【问题描述】:

我有一个应该返回一组字符串的方法。下面是方法说明:

  • 返回:10 个包含指定字符串的产品名称。 如果有多个同名产品,则在产品名称后加上生产者名称,格式为"<producer> - <product>", 否则简单地返回"<product>"

无法弄清楚如何检查数组中是否有重复的名称,然后根据需要进行编辑

到目前为止我得到了什么:

struct Product {
    let id: String; // unique identifier
    let name: String;
    let producer: String;
}

protocol Shop {

    func addNewProduct(product: Product) -> Bool

    func deleteProduct(id: String) -> Bool
    
    func listProductsByName(searchString: String) -> Set<String>
    
    func listProductsByProducer(searchString: String) -> [String]
}

class ShopImpl: Shop {
    
    private var goodsInTheShopDictionary: [String: Product] = [:]
        
    func addNewProduct(product: Product) -> Bool {
        let result = goodsInTheShopDictionary[product.id] == nil
        if result {
            goodsInTheShopDictionary[product.id] = product
        }
        return result
    }
    
    func deleteProduct(id: String) -> Bool {
        let result = goodsInTheShopDictionary[id] != nil
        if result {
            goodsInTheShopDictionary.removeValue(forKey: id)
        }
        return result
    }

    
    func listProductsByName(searchString: String) -> Set<String> {
        var result = Set<String>()
    
        let searchedItems = goodsInTheShopDictionary.filter{ $0.value.name.contains(searchString) }
        let resultArray = searchedItems.map{ $0.value }
        
        
        
        result = Set(searchedItems.map{ $0.value.name })
        if result.count > 10 {
            result.removeFirst()
        }

        return result
        
    }
    

}


【问题讨论】:

  • 不是将 value.name 映射到 resultArray 上的 Set 循环中,而是检查每个名称是否在结果中(可以是数组或集合),然后添加它或将其与生产者名称一起添加。然后对该结果使用 prefix(10) 以获取前 10 个或在找到 10 个项目后中断循环。

标签: arrays swift dictionary


【解决方案1】:

如果你想实现这一点,你需要迭代你resultArray并将producerproduct保存到另一个数组中。在每次迭代中,您都需要检查数组 allready 是否包含产品名称本身或 allready 修改版本。

一个可能的实现是这样的:

var result = [(producer: String, product: String)]()
// iterate over the first 10 results
for item in resultArray.prefix(10){
    if let index = result.firstIndex(where: { _ , product in
        product == item.name
    }){
        // the result array allready contains the exact product name
        // so we need to convert the name allready in the list
        let oldProduct = (producer: result[index].producer, product: "(result[index].producer) (result[index].product)")
        result[index] = oldProduct
        // add the new one
        result.append((producer: item.producer, product: "(item.producer) (item.name)"))
    }
    else if !result.filter({ $0.product.components(separatedBy: " ").contains(item.name)}).isEmpty {
        // if the result array allready contains a modified version of the name
        result.append((producer: item.producer, product: "(item.producer) (item.name)"))
    } else{
        // if the result array does not contain the product yet
        result.append((producer: item.producer, product: "(item.name)"))
    }
}

let productNames = result.map{ $0.product}

请注意:由于您使用的是 [String: Product],这是一个未排序的字典,因此每次搜索时都会产生不同的结果(如果 resultArray 集合大于 10)。


searchString = name1测试:

var goodsInTheShopDictionary: [String: Product] = Dictionary(uniqueKeysWithValues: (0...20).map { index in
    ("(index)",Product(id: "", name: "name(index)", producer: "producer(index)"))
})

goodsInTheShopDictionary["100"] = Product(id: "11", name: "name1", producer: "producer11")
goodsInTheShopDictionary["101"] = Product(id: "12", name: "name1", producer: "producer12")

结果:

["name13", "producer12 name1", "name 10", "name 19", "producer 11 name1", "name17", "name14", "name18", "producer1 name1", "name16"]

【讨论】:

    猜你喜欢
    • 2015-03-28
    • 2016-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-14
    • 2012-11-30
    • 1970-01-01
    • 2017-02-03
    相关资源
    最近更新 更多