0

I'm trying to create an object if it doesn't exist in an array and delete one if it's duplicated. The following code can successfully determine if an object already exists and if it's duplicated, what I'm not sure about is how to capture the actual object inside the IF statement if existanceCount == 2{} within the contains(where:) method to be able to delete one of the duplicate objects.

How can I capture an object inside the contains(where:) method?

I basically need to access {$0} inside the contains(where:) method.

func dogCleanup(){
    let dogNames = ["Teddy","Browny","Mia"]

    var existanceCount = 0
    for i in 0..<dogNames.count{
        if dogs.contains(where: {$0.name == dogNames[i]}){
            existanceCount += 1
            if existanceCount == 2{
                print("Dog exists 2 times, delete it")
                // how can I capture one of the duplicate objects
            }
        }else{
            print("Does NOT exist, add dog...")
        }
    }
}

Here is in context what I'm expecting after calling the dogCleanup() method.

Example 1

    let dogs = [Dog(name: "Teddy"), Dog(name: "Browny"),Dog(name: "Mia")] // objects in Core Data
    let dogNames = ["Teddy","Browny","Mia"] // default dog names

    func dogCleanup(){
        // do nothing, both match
    }
    // What I'm expecting after running the dogCleanup
    Teddy,Browny,Mia 

Example 2

    let dogs = [Dog(name: "Teddy"), Dog(name: "Browny")] // objects in Core Data
    let dogNames = ["Teddy","Browny","Mia"]

    func dogCleanup(){
        // add Mia since it doesn't exist in Core Data
    }
    // What I'm expecting after running the dogCleanup
    Teddy, Browny, Mia 

Example 3

    let dogs = [Dog(name: "Teddy"), Dog(name: "Browny"), Dog(name: "Browny")] // objects in Core Data
    let dogNames = ["Teddy","Browny","Mia"] // default dog names

    func dogCleanup(){
        // delete one Browny and add Mia since it doesn't exist in Core Data
    }
    // What I'm expecting after running the dogCleanup
    Teddy, Browny, Mia 

Example 4

    let dogs = [Dog(name: "Teddy"), Dog(name: "Browny"), Dog(name: "Browny"), Dog(name: "Shadow")] // objects in Core Data
    let dogNames = ["Teddy","Browny","Mia"] // default dog names

    func dogCleanup(){
        // delete one Browny, add Mia and leave Shadow
    }
    // What I'm expecting after running the dogCleanup
    Teddy, Browny, Mia, Shadow
8
  • 2
    Use first(where:) or firstIndex(where:) instead to get the object or the index for the object. Commented Aug 28, 2023 at 12:49
  • 2
    For better solutions to find and remove duplicates see this question Commented Aug 28, 2023 at 12:53
  • 1
    Does this need to be an array, specifically? It looks like a Set or Dictionary would be a more appropriate data structure that makes these kinds of operation completely trivial
    – Alexander
    Commented Aug 28, 2023 at 14:46
  • 1
    So if a dog name is a duplicate but not in the dogNames array it is ok and should not be removed? Commented Aug 28, 2023 at 15:54
  • 1
    @fs_tigre Array(Set(dogsArray)) that wouldn't work, because you would be uniqueing according to the definitions of Dog.hash(into:) and Dog.==, which probably aren't based solely off the name.
    – Alexander
    Commented Aug 28, 2023 at 19:08

1 Answer 1

1

Actually if you call this method always to pick a dog by name and create a new dog if it doesn't exist you don't have to check for more than one occurrence of the object.

func getDog(by name: String) -> Dog {

    if let dog = dogs.first(where: {$0.name == name}){
        return dog
    } else {
        dogs.append(Dog(name: name))
    }
}
18
  • 2
    It's unclear how the categories are related to the duplicates. Does it mean that there should be only one dog per category?
    – vadian
    Commented Aug 28, 2023 at 16:12
  • 2
    My suggested approach is to avoid duplicates by checking before creating a new record. This is more efficient.
    – vadian
    Commented Aug 28, 2023 at 18:27
  • 1
    The check I'm doing is to create and remove duplicates for items that may get duplicated due to CloudKit Sync. These are default-objects that will be created at the start of the app but can get duplicated if the user uninstalls and reinstalls the app with CloudKit on.
    – fs_tigre
    Commented Aug 28, 2023 at 19:06
  • 1
    @fs_tigre I'm interested in providing an answer here, but I'm a little bit lost. There have been a lot of edits, two similar-but-different code snippets in the original (I don't understand how they're related), and multiple different use patterns. I'm getting lost in the sauce. Can you please edit your question down to focus on the final set of findings/details/usecases, and in particular answer some questions: 10 Can you apply unquing by-construction (so dupes never arise in the first place), or must you be able to dedupe an array that already has dupes? 2) are you doing this on every ...
    – Alexander
    Commented Aug 28, 2023 at 19:11
  • 2
    …that may get duplicated due to CloudKit Sync. This cannot happen if you take care of checking for duplicates as I suggested (on all devices).
    – vadian
    Commented Aug 28, 2023 at 19:23

Not the answer you're looking for? Browse other questions tagged or ask your own question.