Unique Objects inside a Array Swift

Here is an Array extension to return the unique list of objects based on a given key:

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

using this you can so this

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

this has the advantage of not requiring the Hashable and being able to return an unique list based on any field or combination


If Product conforms to Equatable, where a product is equal based on it's subcategory (and you don't care about order), you can add the objects to a set, and take an array from that set:

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

or

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

You can use Swift Set:

let array = [product,product2,product3]

let set = Set(array)

You have to make Product conform to Hashable (and thus, Equatable) though:

class Product : Hashable {
    var subCategory = ""

    var hashValue: Int { return subCategory.hashValue }
}

func ==(lhs: Product, rhs: Product) -> Bool {
    return lhs.subCategory == rhs.subCategory
}

And, if Product was a NSObject subclass, you have to override isEqual:

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

Clearly, modify those to reflect other properties you might have in your class. For example:

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
}

Tags:

Arrays

Ios

Swift