Removing duplicate elements from an array in Swift

后端 未结 30 2016
遥遥无期
遥遥无期 2020-11-22 00:07

I might have an array that looks like the following:

[1, 4, 2, 2, 6, 24, 15, 2, 60, 15, 6]

Or, reall

30条回答
  •  无人及你
    2020-11-22 00:57

    here I've done some O(n) solution for objects. Not few-lines solution, but...

    struct DistinctWrapper : Hashable {
        var underlyingObject: T
        var distinctAttribute: String
        var hashValue: Int {
            return distinctAttribute.hashValue
        }
    }
    func distinct(source: S,
                                                                    distinctAttribute: (T) -> String,
                                                                    resolution: (T, T) -> T) -> [T] {
        let wrappers: [DistinctWrapper] = source.map({
            return DistinctWrapper(underlyingObject: $0, distinctAttribute: distinctAttribute($0))
        })
        var added = Set>()
        for wrapper in wrappers {
            if let indexOfExisting = added.indexOf(wrapper) {
                let old = added[indexOfExisting]
                let winner = resolution(old.underlyingObject, wrapper.underlyingObject)
                added.insert(DistinctWrapper(underlyingObject: winner, distinctAttribute: distinctAttribute(winner)))
            } else {
                added.insert(wrapper)
            }
        }
        return Array(added).map( { return $0.underlyingObject } )
    }
    func == (lhs: DistinctWrapper, rhs: DistinctWrapper) -> Bool {
        return lhs.hashValue == rhs.hashValue
    }
    
    // tests
    // case : perhaps we want to get distinct addressbook list which may contain duplicated contacts like Irma and Irma Burgess with same phone numbers
    // solution : definitely we want to exclude Irma and keep Irma Burgess
    class Person {
        var name: String
        var phoneNumber: String
        init(_ name: String, _ phoneNumber: String) {
            self.name = name
            self.phoneNumber = phoneNumber
        }
    }
    
    let persons: [Person] = [Person("Irma Burgess", "11-22-33"), Person("Lester Davidson", "44-66-22"), Person("Irma", "11-22-33")]
    let distinctPersons = distinct(persons,
        distinctAttribute: { (person: Person) -> String in
            return person.phoneNumber
        },
        resolution:
        { (p1, p2) -> Person in
            return p1.name.characters.count > p2.name.characters.count ? p1 : p2
        }
    )
    // distinctPersons contains ("Irma Burgess", "11-22-33") and ("Lester Davidson", "44-66-22")
    

提交回复
热议问题