You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中Shop协议对应ShopImpl类的方法实现疑问咨询

Shop协议实现思路与完整代码

核心问题解决

Shop是定义行为的协议,ShopImpl作为它的实现类,需要在内部定义内存存储结构来保存Product对象。由于Product的id是唯一标识,用[String: Product]字典存储是最优选择——通过id作为key,增删查操作效率高,且能天然保证id的唯一性。

完整实现代码

struct Product {
    let id: String; // 唯一标识符
    let name: String;
    let producer: String;
}

protocol Shop {
    /// 向商店添加新产品
    /// - 参数product: 要添加的产品
    /// - 返回值: 如果已存在相同id的产品返回false,否则返回true
    func addNewProduct(product: Product) -> Bool
    
    /// 根据id删除产品
    /// - 返回值: 如果存在该id的产品返回true,否则返回false
    func deleteProduct(id: String) -> Bool
    
    /// 返回包含指定字符串的最多10个产品名称
    /// 如果有多个产品同名,格式为"<生产者> - <产品名>",否则直接返回"<产品名>"
    func listProductsByName(searchString: String) -> Set<String>
    
    /// 返回生产者名称包含指定字符串的最多10个产品名称,结果按生产者排序
    func listProductsByProducer(searchString: String) -> [String]
}

class ShopImpl: Shop {
    // 私有字典存储产品,key为产品id,保证唯一性
    private var products: [String: Product] = [:]
    
    func addNewProduct(product: Product) -> Bool {
        // 检查id是否已存在,存在则返回false
        guard products[product.id] == nil else {
            return false
        }
        // 不存在则添加到字典
        products[product.id] = product
        return true
    }
    
    func deleteProduct(id: String) -> Bool {
        // 尝试删除指定id的产品,删除成功(原存在)返回true,否则返回false
        guard products.removeValue(forKey: id) != nil else {
            return false
        }
        return true
    }
    
    func listProductsByName(searchString: String) -> Set<String> {
        // 过滤出名称包含搜索字符串的产品
        let filteredProducts = products.values.filter { $0.name.contains(searchString) }
        
        // 统计每个产品名称的出现次数,用于判断是否需要添加生产者前缀
        var nameOccurrenceCount: [String: Int] = [:]
        for product in filteredProducts {
            nameOccurrenceCount[product.name, default: 0] += 1
        }
        
        var result: Set<String> = []
        for product in filteredProducts {
            // 最多返回10个结果
            guard result.count < 10 else { break }
            
            if nameOccurrenceCount[product.name] ?? 0 > 1 {
                result.insert("\(product.producer) - \(product.name)")
            } else {
                result.insert(product.name)
            }
        }
        return result
    }
    
    func listProductsByProducer(searchString: String) -> [String] {
        // 过滤出生产者名称包含搜索字符串的产品
        let filteredProducts = products.values.filter { $0.producer.contains(searchString) }
        
        // 按生产者名称排序
        let sortedProducts = filteredProducts.sorted { $0.producer < $1.producer }
        
        // 提取产品名称,最多取10个
        return sortedProducts.prefix(10).map { $0.name }
    }
}

测试用例验证

执行以下测试代码可验证实现正确性,所有断言均会通过:

func test(lib: Shop) {
    assert(!lib.deleteProduct(id: "1"))
    assert(lib.addNewProduct(product: Product(id: "1", name: "1", producer: "Lex")))
    assert(!lib.addNewProduct(product: Product(id: "1", name: "any name because we check id only", producer: "any producer")))
    assert(lib.deleteProduct(id: "1"))
    assert(lib.addNewProduct(product: Product(id: "3", name: "Some Product3", producer: "Some Producer2")))
    assert(lib.addNewProduct(product: Product(id: "4", name: "Some Product1", producer: "Some Producer3")))
    assert(lib.addNewProduct(product: Product(id: "2", name: "Some Product2", producer: "Some Producer2")))
    assert(lib.addNewProduct(product: Product(id: "1", name: "Some Product1", producer: "Some Producer1")))
    assert(lib.addNewProduct(product: Product(id: "5", name: "Other Product5", producer: "Other Producer4")))
    assert(lib.addNewProduct(product: Product(id: "6", name: "Other Product6", producer: "Other Producer4")))
    assert(lib.addNewProduct(product: Product(id: "7", name: "Other Product7", producer: "Other Producer4")))
    assert(lib.addNewProduct(product: Product(id: "8", name: "Other Product8", producer: "Other Producer4")))
    assert(lib.addNewProduct(product: Product(id: "9", name: "Other Product9", producer: "Other Producer4")))
    assert(lib.addNewProduct(product: Product(id: "10", name: "Other Product10", producer: "Other Producer4")))
    assert(lib.addNewProduct(product: Product(id: "11", name: "Other Product11", producer: "Other Producer4")))
    
    var byNames: Set<String> = lib.listProductsByName(searchString: "Product")
    assert(byNames.count == 10)
    
    byNames = lib.listProductsByName(searchString: "Some Product")
    assert(byNames.count == 4)
    assert(byNames.contains("Some Producer3 - Some Product1"))
    assert(byNames.contains("Some Product2"))
    assert(byNames.contains("Some Product3"))
    assert(!byNames.contains("Some Product1"))
    assert(byNames.contains("Some Producer1 - Some Product1"))
    
    var byProducer: [String] = lib.listProductsByProducer(searchString: "Producer")
    assert(byProducer.count == 10)

    byProducer = lib.listProductsByProducer(searchString: "Some Producer")
    assert(byProducer.count == 4)
    assert(byProducer[0] == "Some Product1")
    assert(byProducer[1] == "Some Product2" || byProducer[1] == "Some Product3")
    assert(byProducer[2] == "Some Product2" || byProducer[2] == "Some Product3")
    assert(byProducer[3] == "Some Product1")
}

test(lib: ShopImpl())

内容的提问来源于stack exchange,提问作者bowtie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 18:55:39