数组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集合仅取决于子类别,则比较应完全取决于子类别。 这可能是一个很大的麻烦,如果你需要比较你的产品的其他方式