Removing Duplicates From Array of Custom Objects Swift

后端 未结 4 1407
孤独总比滥情好
孤独总比滥情好 2020-11-30 08:04

I have a custom class defined as follows :

class DisplayMessage : NSObject {
var id : String?
var partner_image : UIImage?
var partner_name : String?
var la         


        
相关标签:
4条回答
  • 2020-11-30 08:10

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

    extension Array {
    
        func uniques<T: Hashable>(by keyPath: KeyPath<Element, T>) -> [Element] {
            return reduce([]) { result, element in
                let alreadyExists = (result.contains(where: { $0[keyPath: keyPath] == element[keyPath: keyPath] }))
                return alreadyExists ? result : result + [element]
            }
        }
    }
    
    

    Usage:

    myChats.uniques(by: \.id)
    
    0 讨论(0)
  • 2020-11-30 08:15

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

    for your example do:

    let uniqueMessages = messages.unique{$0.id ?? ""}
    
    0 讨论(0)
  • 2020-11-30 08:21

    You can do it with a set of strings, like this:

    var seen = Set<String>()
    var unique = [DisplayMessage]
    for message in messagesWithDuplicates {
        if !seen.contains(message.id!) {
            unique.append(message)
            seen.insert(message.id!)
        }
    }
    

    The idea is to keep a set of all IDs that we've seen so far, go through all items in a loop, and add ones the IDs of which we have not seen.

    0 讨论(0)
  • 2020-11-30 08:27

    Create a free duplicate version of an Array, using equality comparisons based on a given key

    public extension Sequence {
    
        public func uniq<Id: Hashable >(by getIdentifier: (Iterator.Element) -> Id) -> [Iterator.Element] {
            var ids = Set<Id>()
            return self.reduce([]) { uniqueElements, element in
                if ids.insert(getIdentifier(element)).inserted {
                    return uniqueElements + CollectionOfOne(element)
                }
                return uniqueElements
            }
        }
    
    
       public func uniq<Id: Hashable >(by keyPath: KeyPath<Iterator.Element, Id>) -> [Iterator.Element] {
          return self.uniq(by: { $0[keyPath: keyPath] })
       }
    }
    
    public extension Sequence where Iterator.Element: Hashable {
    
        var uniq: [Iterator.Element] {
            return self.uniq(by: { (element) -> Iterator.Element in
                return element
            })
        }
    
    }
    

    Usage

    let numbers =  [1,2,3,4,5,6,7,1,1,1,]
    let cars = [Car(id:1), Car(id:1), Car(id:2)]
    
    numbers.uniq
    cars.uniq(by: { $0.id})
    cars.uniq(by: \Car.id)
    cars.uniq(by: \.id)
    
    0 讨论(0)
提交回复
热议问题