访问结构数组中结构的元素

Posted

技术标签:

【中文标题】访问结构数组中结构的元素【英文标题】:Access element of the struct in array of structs 【发布时间】:2021-09-20 22:10:05 【问题描述】:

您好,我的任务是实现具有两个功能的 Fleet 协议:

addNewCar - 向 Fleet 添加一个新的汽车对象。 - 参数汽车:要添加到车队的汽车 - 返回:如果车队中已经存在具有相同 id 的汽车,则返回 false,否则返回 true。

deleteCar - 从 Fleet 中删除具有指定 id 的汽车。 - 返回:如果车队中存在具有相同 id 的汽车,则返回 true,否则返回 false。

listCarsByModel - 返回 10 个包含指定字符串的汽车模型。 如果有几辆相同型号的汽车,则以“品牌-汽车”的格式将品牌名称添加到汽车型号中, 否则只返回“汽车”。

listCarsByBrand - 返回 10 个品牌包含指定字符串的车型, 结果按品牌排序。

struct Car 
    let id: String; // unique identifier
    let model: String;
    let brand: String;


protocol Fleet 
    func addNewCar(car: Car) -> Bool

    func deleteCar(id: String) -> Bool

    func listCarsByModel(searchString: String) -> Set<String>

    func listCarsByBrand(searchString: String) -> [String]




class FleetImpl: Fleet 
    var cars: [Car] = []

    func addNewCar(car: Car) -> Bool 
        if let i = cars.firstIndex(where:  $0.id == car.id ) 
            print(i)
            return false
         else 
            cars.append(car)
            print(car)
            return true
        
    

    func deleteCar(id: String) -> Bool 

        return true
    

    func listCarsByModel(searchString: String) -> Set<String> 

    

    func listCarsByBrand(searchString: String) -> [String] 

    


我使用了方法 firstIndex(where:)。但是该函数将新车添加到具有现有 ID 的数组中。 (即两辆或多辆具有相同 id 的汽车)

如何访问 Car 结构的“id”属性以操作该数据? 请帮帮我

这是测试代码:

func test(fleet: Fleet) 
    assert(!fleet.deleteCar(id: "1"))
    assert(fleet.addNewCar(car: Car(id: "1", model: "1", brand: "Lex")))
    assert(!fleet.addNewCar(car: Car(id: "1", model: "any name because we check id only", brand: "any brand")))
    assert(fleet.deleteCar(id: "1"))
    assert(fleet.addNewCar(car: Car(id: "3", model: "Some Car3", brand: "Some Brand2")))
    assert(fleet.addNewCar(car: Car(id: "4", model: "Some Car1", brand: "Some Brand3")))

    var byModels: Set<String> = fleet.listCarsByModels(searchString: "Car")
    assert(byModels.count == 10)

byModels = fleet.listCarsByModels(searchString: "Some Car")
    assert(byModels.count == 4)
    assert(byModels.contains("Some Brand3 - Some Car1"))
    assert(byModels.contains("Some Car2"))
    assert(byModels.contains("Some Car3"))
    assert(!byModels.contains("Some Car1"))
    assert(byModels.contains("Some Brand1 - Some Car1"))

var byBrand: [String] = fleet.listCarsByBrand(searchString: "Brand")
    assert(byBrand.count == 10)

byBrand = fleet.listCarsByBrand(searchString: "Some Brand")
    assert(byBrand.count == 4)
    assert(byBrand[0] == "Some Car1")
    assert(byBrand[1] == "Some Car2" || byBrand[1] == "Some Car3")
    assert(byBrand[2] == "Some Car2" || byBrand[2] == "Some Car3")
    assert(byBrand[3] == "Some Car1")


test(fleet: FleetImpl())

【问题讨论】:

“但似乎有些不对劲。” 什么似乎错了? 好像你有一个 错误。协议缺少一个 @Sweeper 抱歉,我已经编辑了问题。该数组不应包含两辆或多辆具有相同 ID 的汽车 @RajaKishan 我的错,已修复 不相关,但这是 Swift:没有尾随分号!如果id 真的是一个唯一标识符,那么 add 方法应该可以工作。如果数组包含多个具有相同 id 的项目,那么您的设计是错误的。 【参考方案1】:

当我们处理unique 元素时,在这种情况下,也许集合而不是数组会更好。另请注意,我使用的是first(where),而不是使用firstIndex(where),这将返回汽车而不是索引。

import UIKit

struct Car: Hashable 
    let id: String
    let model: String
    let brand: String
    
    func hash(into hasher: inout Hasher) 
        hasher.combine(id)
    


protocol Fleet 
    func addNewCar(car: Car) -> Bool
    func deleteCar(id: String) -> Bool
    func listCarsByModel(searchString: String) -> [String]
    func listCarsByBrand(searchString: String) -> [String]


class FleetImpl: Fleet 
    var cars = Set<Car>()

    func addNewCar(car: Car) -> Bool 
        guard !cars.contains(where:  $0.id == car.id ) else  return false 
        
        cars.insert(car)
        return true
    

    func deleteCar(id: String) -> Bool 
        guard let car = cars.first(where:  $0.id == id ) else  return false 
        
        cars.remove(car)
        return true
    
    
    func listCarsByModel(searchString: String) -> [String] 
        let searchedCars = cars.filter  $0.model.lowercased().contains(searchString.lowercased()) .sorted  $0.brand < $1.brand 
        var formattedModels = [String]()
        searchedCars.forEach  car in
            if let car = searchedCars.first(where:  $0.model == car.model && $0.id != car.id ) 
                let carName = [car.model, car.brand].joined(separator: " - ")
                formattedModels.append(carName)
             else 
                formattedModels.append(car.model)
            
        
        return Array(formattedModels.prefix(10))
    
    
    func listCarsByBrand(searchString: String) -> [String] 
        let searchedBrands = cars.filter  $0.brand.lowercased().contains(searchString.lowercased()) .sorted  $0.brand < $1.brand .map  $0.model 
        return Array(searchedBrands.prefix(10))
    
    

【讨论】:

非常感谢您的回答。它工作得很好。还有更多功能要添加。你也介意帮忙吗 @Russ 还有哪些功能需要添加?你能和他们一起更新问题吗? 我已通过添加函数(listCarsByModel 和 listCarsByBrand)来编辑问题。请看一看。非常感谢您的帮助伙伴,非常感谢它 @Russ 我更新了我的答案不是最有效的解决方案,但希望这是你所追求的:) 非常感谢?上帝保佑你

以上是关于访问结构数组中结构的元素的主要内容,如果未能解决你的问题,请参考以下文章

从 Fortran 访问 C++ 结构数组?

从 Fortran 访问 C++ 结构数组?

数据结构入门

将数组作为结构访问与未定义的行为

数据结构:使用面向对象模拟数组

算法与数据结构3