Reputation: 778
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
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
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