Home > Back-end >  Get only duplicate elements from array in swift
Get only duplicate elements from array in swift

Time:05-26

I'm interested in a more elegant way of getting duplicate elements. I need to find them in order to eventually remove them from the subview.

struct People {
    var id: Int
    var name: String
}

let peoples = [
    People(id: 1, name: "Sam"),
    People(id: 2, name: "Tim"),
    People(id: 3, name: "John"),
    People(id: 1, name: "Chris"),
    People(id: 2, name: "David"),
    People(id: 1, name: "Joy")
]

var duplicationPeople: [People] = []
let nondupicatePeople = peoples.reduce(into: [People]()) { one, two in
    if !one.map({$0.id}).contains(two.id) {
        one.append(two)
    } else {
        duplicationPeople.append(two)
    }
}

duplicationPeople.map { print($0) }

// People(id: 1, name: "Chris")
// People(id: 2, name: "David")
// People(id: 1, name: "Joy")

CodePudding user response:

I don't know if you are looking for a more elegant solution, but the most straight forward one would be to save ids you already had before separately, and check them for each element:

var uniquePeople = [People]()
var duplicatePeople = [People]()
var ids = [Int]()

peoples.forEach { person in

    guard !ids.contains(person.id) else {
        duplicatePeople.append(person)
        return
    }

    uniquePeople.append(person)
    ids.append(person.id)
}

Result:

uniquePeople: [
 People(id: 1, name: "Sam"), 
 People(id: 2, name: "Tim"), 
 People(id: 3, name: "John")
]

duplicatePeople: [
 People(id: 1, name: "Chris"), 
 People(id: 2, name: "David"), 
 People(id: 1, name: "Joy")
]

CodePudding user response:

This is basically what you wrote:

var seen: [Int] = []
let dupes = peoples.reduce(into: []) { duplicates, person in
    if seen.contains(person.id) {
        duplicates.append(person)
    }
    else {
        seen.append(person.id)
    }
}

If you are interested in removing duplicates, you might benefit from OrderedSet from https://github.com/apple/swift-collections where you can't have duplicates in the first place, for example:

struct Person: Identifiable, Hashable, Equatable {
    var id: Int
    var name: String

    static func == (lhs: Self, rhs: Self) -> Bool {
        lhs.id == rhs.id
    }
}

let os = OrderedSet(peoples) // = Sam/Tim/John
  • Related