如何在数组中插入不同类型的元素

时间:2019-01-28 11:58:12

标签: ios arrays swift filter

我有一个class,它引用了另一个class。一个学生班级有一个引用模块信息的变量。我想将moduleId插入数组,但是该结构由不同类型的对象组成,并且类型为moduleRef。我想获取moduleId类型的字符串。如何获取ModuleRef形式的moduleId元素。

class Student {
    var firstName: String
    var lastName: String
    var modulesRefs: [ModuleRef]

    var fullName: String {
        return self.firstName + " " + self.lastName
    }

    init(firstName: String, lastName: String, modulesRefs: [ModuleRef]) {
        self.firstName = firstName
        self.lastName = lastName
        self.modulesRefs = modulesRefs
    }

    func addModuleId(_ moduleId: String) {
        self.modulesRefs.insert(moduleId, at: 0)
    }

     func removeModuleId(_ moduleId: String) {
        self.modulesRefs = self.modulesRefs.filter { $0.moduleId != moduleId }
    }
}

class ModuleRef {
    var moduleName: String
    var moduleId: String
    var moduleStartdate: Int

    init(moduleName: String, moduleId: String, moduleStartdate: Int) {
        self.moduleName = moduleName
        self.moduleId = moduleId
        self.moduleStartdate = moduleStartdate
    }
}
  

无法将类型为“字符串”的值转换为预期的参数类型为“ ModuleRef”

6 个答案:

答案 0 :(得分:1)

在您的代码中,您强制设置了class ModuleRef { ... }个值,并且只传递了一个值moduleId,并将其添加到Array的{​​{1}}中错误的做法。因此,根据您在此处所说的内容,是代码的更新代码:

ModuleRef

此外,您还可以为所有将变量设置为class Student { var firstName: String var lastName: String var modulesRefs: [ModuleRef] var fullName: String { return self.firstName + " " + self.lastName } init(firstName: String, lastName: String, modulesRefs: [ModuleRef]) { self.firstName = firstName self.lastName = lastName self.modulesRefs = modulesRefs } func addModuleId(_ moduleId: String) { // This will be your updated intializer where you can pass any value you want and other will be taken as default value let moduleRef = ModuleRef(moduleId: moduleId) self.modulesRefs.insert(moduleRef, at: 0) } func removeModuleId(_ moduleId: String) { self.modulesRefs = self.modulesRefs.filter { $0.moduleId != moduleId } } } class ModuleRef { var moduleName: String var moduleId: String var moduleStartdate: Int /// Here you can provide all the default values which you don't want to pass init(moduleName: String = "", moduleId: String = "", moduleStartdate: Int = 0) { self.moduleName = moduleName self.moduleId = moduleId self.moduleStartdate = moduleStartdate } } 的变量传递nil值。让我知道,如果您有任何困惑!

答案 1 :(得分:1)

您不能仅通过传递ModuleRef来插入String

您需要创建一个实例,例如添加学生的全名和当前日期的UNIX时间戳

func addModuleId(_ moduleId: String) {
    let moduleRef = ModuleRef(moduleName: self.fullName, 
                              moduleId: moduleId, 
                              moduleStartDate: Int(Date().timeIntervalSince1970))
    self.modulesRefs.insert(moduleRef, at: 0)
}

要删除一个对象,效率更高,但是该类必须符合Equatable

func removeModuleId(_ moduleId: String) {
    guard let index = self.modulesRefs.firstIndex(where: {$0.moduleId == moduleId}) else { return }
    self.modulesRefs.remove(at: index)
}

我什至将moduleStartDate声明为Date

答案 2 :(得分:1)

您可以将类型ModuleRef的值插入该数组。所以我可以将功能修改为:

func addModuleId(_ moduleId: String) {
        let module = ModuleRef(moduleName: "", moduleId: moduleId, moduleStartdate: 0)
        self.modulesRefs.insert(module, at: 0)
    }

    func removeModuleId(_ moduleId: String) {
        modulesRefs.removeAll(where: { $0.moduleId == moduleId })
    }

注意:如果您不需要一直使用moduleNamemoduleStartdate,则可以将其标记为“可选”。

答案 3 :(得分:0)

您需要将Array类型更新为Any,如下所示:

var modulesRefs: [Any] 

从数组访问值时,

if let moduleRef = modulesRefs[index] as? ModuleRef {

} else if let str = modulesRefs[index] as? String  {

}

答案 4 :(得分:0)

您要尝试执行的操作实际上意味着您的设计存在缺陷。

如果您需要调用student.addModuleId(moduleId)的功能,这意味着Student不应包含ModuleRef的数组。 (或者至少有一种机制可以通过其ID提取整个ModuleRef,然后将其ModuleRef插入数组中)

话虽这么说,在弄清楚modules: [ModuleRef]moduleIds: [String]的设计之后,您仍然可以使用以下东西:

Equatable协议。如果您使ModuleRef符合Equatable协议,并与id检查其相等性,那么Swift将为您提供remove(element:_)方法的访问权限,您不再需要{ {1}}方法。

或者,如果所有removeModuleId()都是唯一的,则您也可以实现ModuleId协议,并使用Hashable而不是数组来具有O(1)删除和插入方法。 (现在,删除功能需要O(n)时间)

答案 5 :(得分:-1)

您需要创建一个 Any 类型的数组。

var modulesRefs: [Any] = []

您可以像这样在数组中添加元素...

modulesRefs.append("Test string")
let obj = ModuleRef(...)
modulesRefs.append(obj)

访问元素时,您需要使用if letguard let来安全地检查其类型。

例如

  for obj in modulesRefs {
    if let strType = obj as? String {
       print("\(obj) is string type")
    } else if let moduleRefObj = obj as? ModuleRef {
       print("\(obj) is ModuleRef type")
  }