2

我制作了一个简单的结构并实现了 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

4 回答 4

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为 an Int,因为Strings 的效率远低于Ints 并且使用 a 没有意义String

还可以考虑将此属性存储在某处,以便每次收到新模型时,您都可以这样做

modelSet.unionInPlace(newModels)
于 2016-07-02T23:05:15.300 回答
2

使用 aSet而不是Array.

于 2016-07-01T21:07:38.687 回答
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!})

无需使结构 Equatable。

请注意,如果您的数组非常大,并且您可能想要考虑在源头过滤插入到您的数组中,这将不会有效。

于 2016-07-02T00:00:04.610 回答
1

我同意你最好使用 Set。您应该能够使用 Array 初始化 Set,例如 var arrayOfModel: Set = [val1, val2, val3]。但是因为您使用的是自定义类型,所以您需要确保 MyModelStruct 符合 hashable。 这个链接有一个很好的解释

但是如果你想使用一个数组,那么你需要改变

let areEqual = rhs.id == lhs.id

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

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

在回答您的问题时,是的,您确实需要遍历数组。

于 2016-07-01T21:20:43.313 回答