I wanted to filter the entire array just by the first 4 characters of [i].name
You can achieve this by filtering the array based on the substring value of the name, as follows:
let filteredArray = collectionArray.filter {
$0.name.substring(to: $0.name.index($0.name.startIndex, offsetBy: 4)).lowercased() == "pk00"
// or instead of "pk00", add the first 4 characters you want to compare
}
filteredArray will be filled based on what is the compared string.
Hope this helped.
Answer from Ahmad F on Stack OverflowVideos
How to define a map in Swift?
What is mapValues in Swift dictionary?
How to map dictionary to model in Swift?
I wanted to filter the entire array just by the first 4 characters of [i].name
You can achieve this by filtering the array based on the substring value of the name, as follows:
let filteredArray = collectionArray.filter {
$0.name.substring(to: $0.name.index($0.name.startIndex, offsetBy: 4)).lowercased() == "pk00"
// or instead of "pk00", add the first 4 characters you want to compare
}
filteredArray will be filled based on what is the compared string.
Hope this helped.
If you want to group all data automatically by their name prefix. You could use a reducer to generate a dictionary of grouped items. Something like this:
let groupedData = array.reduce([String: [String]]()) { (dictionary, myStruct) in
let grouper = myStruct.name.substring(to: myStruct.name.index(myStruct.name.startIndex, offsetBy: 4))
var newDictionart = dictionary
if let collectionStructs = newDictionart[grouper] {
newDictionart[grouper] = collectionStructs + [myStruct.name]
} else {
newDictionart[grouper] = [myStruct.name]
}
return newDictionart
}
This will produce a dictionary like this:
[
"pk00": ["pk00_pt01", "pk00_pt02", "pk00_pt03"],
"pk01": ["pk01_pt01", "pk01_pt02", "pk01_pt03", "pk01_pt04", "pk01_pt05", "pk01_pt06", "pk01_pt07"],
"pk02": ["pk02_pt08"]
]
There are exactly two cases where the Swift compiler infers the return type of a closure automatically:
- In a "single-expression closure," i.e. the closure body consists of a single expression only (with or without explicit closure parameters).
- If the type can be inferred from the calling context.
None of this applies in
let inActionPersons = persons.map { (var p) in
p.active = false
return p
}
or
let a = persons.map { p in
var p1 = p
p1.active = false
return p1
}
and that's why you have to specify the return type explicitly as in Kametrixom's answer.
Example of a single-expression closure:
let inActionPersons = persons.map { p in
Person(firstName: p.firstName, lastName: p.lastName, active: false)
}
and it would compile with (var p) in or (p : Person) in as well, so this has nothing to do with whether the closure arguments are given
explicitly in parentheses or not.
And here is an example where the type is inferred from the calling context:
let a : [Person] = persons.map { p in
var p1 = p
p1.active = false
return p1
}
The result of map() must be a [Person] array, so map needs
a closure of type Person -> Person, and the compiler infers
the return type Person automatically.
For more information, see "Inferring Type From Context" and "Implicit Returns from Single-Expression Closures" in the "Closures" chapter in the Swift book.
When using the brackets for arguments so that var works, you have to put the return type as well:
let inActionPersons = persons.map { (var p) -> Person in
p.active = false
return p
}