Clean way to filter an array of dictionaries by unique dictionary values

前端 未结 2 1540
情深已故
情深已故 2021-01-14 06:04

Say I have an object:

struct Foo {
    let id: Int
    let bar: Int
}

Now I have 5 of these objects in an array:

let foo1 =         


        
2条回答
  •  暖寄归人
    2021-01-14 06:44

    One possible approach is to use a Set which keeps track of which bar values have already been seen:

    var seenBarValues = Set()
    let filteredArray = fooArray.filter { foo in
        if seenBarValues.contains(foo.bar) {
            // We already had a `Foo` with this `bar` value: skip.
            return false 
        } else {
            // First `Foo` with this `bar` value: remember and include.
            seenBarValues.insert(foo.bar)
            return true
        }
    }
    

    As @Hamish correctly pointed out, this can be shortened to

    var seenBarValues = Set()
    let filteredArray = fooArray.filter { 
        seenBarValues.insert($0.bar).inserted
    }
    

    using the fact that

    public mutating func insert(_ newMember: Element) -> (inserted: Bool, memberAfterInsert: Element)
    

    returns a tuple whose first member indicates if an element equal to the newly inserted one was already present in the set.

提交回复
热议问题