Reputation: 1461
Here is a playground I created to attempt to create the correct filter: What I want to return is all of the outside structs and any inside array values which meet a "text" block which will be inbound from a search bar.
//: Playground - noun: a place where people can play
import UIKit
import Foundation
struct events{
var title:String
var unique:Int
var swimmers_info:[swim_info]
}
struct swim_info{
var name:String
var team:String
}
var arrayEV:[events]
var si1:[swim_info]
var si2:[swim_info]
si1 = [
swim_info(name:"Smith, John",team:"PHNX"),
swim_info(name:"Tenay, Teresa",team:"CRIM")
]
si2 = [
swim_info(name:"Test, Two",team:"PHNX"),
swim_info(name:"Female, Swimmer",team:"SSA")
]
arrayEV = [
events(title: "First Event",unique: 5,swimmers_info:si1),
events(title: "Second Event",unique: 2,swimmers_info:si2)
]
//print(arrayEV)
var newarrayEV1 = arrayEV.filter({(value) -> Bool in
return value.swimmers_info.contains(where: {$0.team == "SSA"})
})
var newarrayEV2 = arrayEV.map({$0.swimmers_info.filter({(value) -> Bool in
return value.team == "SSA"
})})
print(newarrayEV1)
YEILDS [__lldb_expr_42.events(title: "Second Event", unique: 2, swimmers_info: [__lldb_expr_42.swim_info(name: "Test, Two", team: "PHNX"), __lldb_expr_42.swim_info(name: "Female, Swimmer", team: "SSA")])]
**Incorect becuase it yeilds only the second main struct an both sub structs
print(" ")
print(newarrayEV2 )
[[], [__lldb_expr_42.swim_info(name: "Female, Swimmer", team: "SSA")]]
Incorrect because drops all main struct information
print("11")
KINDA CORRECT
I can get the desired result with:
for (index,loop) in arrayEV.enumerated(){
//print(String(describing: index))
//print(loop.swimmers_info)
var new_si = loop.swimmers_info.filter({(value) -> Bool in
return value.team == "SSA"
})
//print(new_si)
arrayEV[index].swimmers_info = new_si
}
however I'm not sure if this is the best way to attack this.
Upvotes: 0
Views: 112
Reputation: 534977
Based on your suggested "solution", I think this is what you're after:
arrayEV = arrayEV.map {
var ev = $0
ev.swimmers_info = ev.swimmers_info.filter {$0.team == "SSA"}
return ev
}
The reason for the rather clumsy-looking three-liner is that we cannot mutate a struct's property unless the reference to the struct itself is a var
reference — but map
provides us with a let
reference ($0
).
Upvotes: 2
Reputation: 3677
Create a method in your event
class which check the text with inner array and with his own title
and tells you that this class fall in match-case
or not
struct events{
var title:String
var unique:Int
var swimmers_info:[swim_info]
func haveSameText(_ text: String) -> Bool {
let filtersArray = swimmers_info.filter { (info) -> Bool in
return info.name.lowercased() == text.lowercased()
}
return filtersArray.count >= 0 || text.lowercased() == title.lowercased()
}
}
struct swim_info{
var name:String
var team:String
}
To filter event array on the base of some text use below method.
var eventArr = [events]()
var filteredArray = eventArr.filter { (event) -> Bool in
return event.haveSameText("text")
}
Upvotes: 1