基于Swift中的struct属性删除数组中的重复结构

时间:2016-07-01 20:47:04

标签: ios iphone swift ios9 ios10

我制作了一个简单的结构并实现了Equatable协议:

extension MyModelStruct: Equatable {}

func ==(lhs: NModelMatch, rhs: NModelMatch) -> Bool {
    let areEqual = lhs.id == rhs.id
    return areEqual
}

public struct MyModelStruct {

    var id : String?
    var staticId : String?

    init(fromDictionary dictionary: NSDictionary){
        id = dictionary["id"] as? String
        ...
}

然后在我的项目中我得到一个[MyModelStruct]数组,我要做的是删除所有具有相同id的MyModelStruct

let val1 = MyModelStruct(id:9, subId:1)
let val2 = MyModelStruct(id:10, subId:1)
let val3 = MyModelStruct(id:9, subId:10)

var arrayOfModel = [val1,val2,val3]; // or set but i do not know how to use a set
var arrayCleaned = cleanFunction[M2,M3] 

我如何制作cleanFunction?

有人可以帮忙吗。 谢谢大家。 Xcode:版本7.3.1

4 个答案:

答案 0 :(得分:3)

我真的不希望别人只是回答,因为它是唯一一个,这就是为什么我告诉你如何使用套装的力量。无论在哪里,都可以使用集合。集提供了快速方法,用于检查元素是否在集合(contains)中,删除元素(remove),组合两个集合(union)等等。通常人们只是想要一个阵列,因为他们熟悉它,但通常一套就是他们真正需要的。话虽如此,以下是如何使用集合:

struct Model : Hashable {
    var id : String?

    var hashValue: Int {
        return id?.hashValue ?? 0
    }
}

func ==(l: Model, r: Model) -> Bool {
    return l.id == r.id
}

let modelSet : Set = [
    Model(id: "a"),
    Model(id: "hello"),
    Model(id: "a"),
    Model(id: "test")
]

// modelSet contains only the three unique Models

要成为集合中类型的唯一要求是Hashable协议(扩展Equatable)。在您的情况下,您只需返回hashValue的基础String即可。如果您的ID始终是一个数字(可能是这个数字),您应该将id的类型更改为Int,因为String的效率远低于Int并且使用String

是没有意义的

另外考虑将此属性存储在某处,以便每次收到新模型时都可以执行

modelSet.unionInPlace(newModels)

答案 1 :(得分:2)

使用Set代替Array

答案 2 :(得分:1)

我同意你最好使用套装。您应该能够使用数组初始化Set,例如var arrayOfModel:Set = [val1,val2,val3]。但是因为您使用的是自定义类型,所以需要确保MyModelStruct符合hashable。 This link has a good explanation

但是如果你想使用数组,则需要更改

let areEqual = rhs.id == lhs.id

let areEqual = rhs.id == lhs.id && rhs.subId == lhs.subId)

您需要修改结构以具有subId属性(并使变量Int而不是String。

在回答你的问题时,是的,你需要对数组进行迭代。

答案 3 :(得分:1)

如果使用此函数扩展Array类型:

  extension Array
  {
     func uniqueValues<V:Equatable>( value:(Element)->V) -> [Element]
     {
        var result:[Element] = []
        for element in self
        {
           if !result.contains({ value($0) == value(element) })
           { result.append(element) }
        }
        return result
     }
  }

您可以使用以下方法清理重复项:

  var arrayCleaned = arrayOfModel.uniqueValues({$0.id!})

无需使结构相等。

请注意,如果您的阵列非常大,这可能不会有效,如果可能的话,您可能需要考虑在源处过滤插入数组。