数组Swift中的唯一对象

我有一个数组,自定义对象。

我想popup重复的对象,具有重复的属性:

let product = Product() product.subCategory = "one" let product2 = Product() product2.subCategory = "two" let product3 = Product() product3.subCategory = "two" let array = [product,product2,product3] 

在这种情况下,popupproduct2 or product3

你可以使用Swift Set

 let array = [product,product2,product3] let set = Set(array) 

你必须使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 } 

而且,如果Product是一个NSObject子类,则必须重写isEqual

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

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

 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 } 

下面是一个数组扩展,用于根据给定的键返回唯一的对象列表:

 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 } } 

使用这个你可以这样

 let unique = [product,product2,product3].unique{$0.subCategory} 

这具有不需要Hashable并能够基于任何字段或组合返回唯一列表的优点

如果Product符合Equatable ,那么根据产品的子类别(并且不关心订单),产品是相等的,您可以将这些对象添加到一个集合中,并从该集合中获取一个数组:

 let array = [product,product2,product3] let set = NSSet(array: array) let uniqueArray = set.allObjects 

要么

 let array = [product,product2,product3] let set = Set(array) let uniqueArray = Array(set) 

如果你的类符合协议Hashable,你想保持原始数组顺序,你可以创build一个扩展如下:

 extension Array where Element: Hashable { var uniqueElements: [Element] { var elements: [Element] = [] for element in self { if let _ = elements.indexOf(element) { print("item found") } else { print("item not found, add it") elements.append(element) } } return elements } } 
 class Product { var subCategory: String = "" } let product = Product() product.subCategory = "one" let product2 = Product() product2.subCategory = "two" let product3 = Product() product3.subCategory = "two" let array = [product,product2,product3] extension Product : Hashable { var hashValue: Int { return subCategory.hashValue } } func ==(lhs: Product, rhs: Product)->Bool { return lhs.subCategory == rhs.subCategory } let set = Set(array) set.forEach { (p) -> () in print(p, p.subCategory) } /* Product one Product two */ 

如果一个项目是否设置的一部分不取决于hashValue,这取决于比较。 如果你的产品符合Hashable,它应该符合Equatable。 如果您需要创build集合仅取决于子类别,则比较应完全取决于子类别。 这可能是一个很大的麻烦,如果你需要比较你的产品的其他方式