数组Swift中的唯一对象

Vin*_*ino 7 arrays ios swift

我有一个带有自定义对象的数组.

我想用重复的属性弹出重复的对象:

let product = Product()
product.subCategory = "one"

let product2 = Product()
product2.subCategory = "two"

let product3 = Product()
product3.subCategory = "two"

let array = [product,product2,product3]
Run Code Online (Sandbox Code Playgroud)

在这种情况下,弹出 product2 or product3

Rob*_*Rob 10

你可以使用Swift Set:

let array = [product,product2,product3]

let set = Set(array)
Run Code Online (Sandbox Code Playgroud)

你必须Product遵守Hashable(因此Equatable):

class Product : Hashable {
    var subCategory = ""

    var hashValue: Int { return subCategory.hashValue }
}

func ==(lhs: Product, rhs: Product) -> Bool {
    return lhs.subCategory == rhs.subCategory
}
Run Code Online (Sandbox Code Playgroud)

并且,如果ProductNSObject子类,则必须覆盖isEqual:

override func isEqual(object: AnyObject?) -> Bool {
    if let product = object as? Product {
        return product == self
    } else {
        return false
    }
}
Run Code Online (Sandbox Code Playgroud)

显然,修改它们以反映您在课堂上可能拥有的其他属性.例如:

class Product : Hashable {
    var category = ""
    var subCategory = ""

    var hashValue: Int { return [category, subCategory].hashValue }
}

func ==(lhs: Product, rhs: Product) -> Bool {
    return lhs.category == rhs.category && lhs.subCategory == rhs.subCategory
}
Run Code Online (Sandbox Code Playgroud)

  • 您应该提到使用set不会保留数组顺序. (3认同)
  • @ user1108474 - 正确,如果它已经符合`Hashable`,那么你不应该声明它再次符合.只是因为没有符合"Hashable"是我能够重现你与我们分享的错误的唯一方法.无论如何,我使用基于`RLMObject`的`Product`测试了它,并且它工作正常(尽管我也必须覆盖`isEqual`,如修订答案中所示). (2认同)

Cip*_*rau 9

这是一个Array扩展,用于根据给定的键返回唯一的对象列表:

extension Array {
    func unique<T:Hashable>(map: ((Element) -> (T)))  -> [Element] {
        var set = Set<T>() //the unique list kept in a Set for fast retrieval
        var arrayOrdered = [Element]() //keeping the unique list of elements but ordered
        for value in self {
            if !set.contains(map(value)) {
                set.insert(map(value))
                arrayOrdered.append(value)
            }
        }

        return arrayOrdered
    }
}
Run Code Online (Sandbox Code Playgroud)

使用这个你可以这样

let unique = [product,product2,product3].unique{$0.subCategory}
Run Code Online (Sandbox Code Playgroud)

这样做的好处是不需要Hashable,并且能够根据任何字段或组合返回唯一列表