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 id
s 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