How to remove a pair from a dictionary for a specified key?

I want to write a function with a parameter, which shall be used for a comparison with a key of a dictionary. The function iterates a collection and checks if the case has a pair with this key. If it has, I want to remove that pair, leave the other in that case and move on with the next case.

I've created a function filterAndExtract(). However it only iterates and do nothing. When comparing (Bool) the parameter and the key in each case, it doesn't work as expected. I want to know how to identify a key in a pair, so I can do stuff with the cases in the collection. Thanks in advance!

enum Tags: String {
     case one = "One"
     case two = "Two"
     case three = "Three"
}

struct Example {
     var title: String
     var pair: [Tags: String]
}

let cases = [
     Example(title: "Random example One", pair: [Tags.one: "First preview", Tags.two: "Second preview"]),
     Example(title: "Random example Two", pair: [Tags.two: "Thrid preview", Tags.three: "Forth preview"]),
     Example(title: "Random example Three", pair: [Tags.three: "Fifth preview", Tags.one: "Sixth preview"])
]

func filterAndExtract(collection: [Example], tag: Tags) {
    for var item in collection {
        let keys = item.pair.keys

        for key in keys {
            if key == tag {
                item.pair.removeValue(forKey: key)
            }
        }
    }

    for i in collection {
        print("\(i.title) and \(i.pair.values) \nNEXT TURN--------------------------------------------------\n")
    }
}

//Results:

//Random example One and ["Second preview", "First preview"] 
//NEXT TURN--------------------------------------------------

//Random example Two and ["Thrid preview", "Forth preview"] 
//NEXT TURN--------------------------------------------------

//Random example Three and ["Fifth preview", "Sixth preview"] 
//NEXT TURN--------------------------------------------------

//Solution (how I want it to look at the end):
for var i in cases {
    i.pair.removeValue(forKey: .three)
    print("\(i.title) and \(i.pair.values) \nNEXT TURN--------------------------------------------------\n")
}
//Random example One and ["Second preview", "First preview"] 
//NEXT TURN--------------------------------------------------

//Random example Two and ["Thrid preview"] 
//NEXT TURN--------------------------------------------------

//Random example Three and ["Sixth preview"] 
//NEXT TURN--------------------------------------------------

Upvotes: 0

Views: 135

Answers (2)

user11701404
user11701404

Reputation:

First of all, it's much more cleaner and reliable if you encapsulate the remove function into the Example {

struct Example {
    var title: String
    var pair: [Tags: String]

    mutating func remove(key: Tags) -> String? {
        return pair.removeValue(forKey: key)
    }
}

Second of all, you can use map for tasks like this:

func filterAndExtract(collection: [Example], tag: Tags) -> [Example] {
    return collection.map { item -> Example in
        var edited = item
        edited.remove(key: tag)
        print("\(edited.title) and \(edited.pair.values) \nNEXT TURN--------------------------------------------------\n")
        return edited
    }
}

I return some values in both functions, so you can use them if you want.

Upvotes: 1

vadian
vadian

Reputation: 285079

Swift collections are value types. Whenever you assign a collection to a variable you'll get a copy of the object.

To modify the parameter collections you have to make it mutable and you have to modify the value directly inside collections.

func filterAndExtract(collection: [Example], tag: Tags) {
    var collection = collection
    for (index, item) in collection.enumerated() {
        let keys = item.pair.keys

        for key in keys {
            if key == tag {
                collection[index].pair.removeValue(forKey: key)
            }
        }
    }

    for i in collection {
        print("\(i.title) and \(i.pair.values) \nNEXT TURN--------------------------------------------------\n")
    }
}

Upvotes: 2

Related Questions