Reputation: 1223
I am a newbie to swift and i have a new project. I am trying to do a search feature. I have a array of dictionaries, containing firstName and lastName as keys, i need to filter out people based on the firstName which contains the search string
let nameList : [Dictionary<String,String>] =
[["firstName" : "John Sam","lastName" : "Smith"],
["firstName" : "Johnny","lastName" : "Smith"],
["firstName" : "Albert","lastName" : "Smith"],
["firstName" : "Alby","lastName" : "Wright"],
["firstName" : "Smith","lastName" : "Green"]]
As in objective C i could easily do with
[NSPredicate predicatewithformat:"firstName contains[c] %@",searchText]
I also understand that the same predicate can be done on Swift .but i am looking for an equivalent Swift, so that i can gain how to use map and filter. Any help appreciated
Upvotes: 6
Views: 12739
Reputation: 539705
A search corresponding to the predicate operator "CONTAINS[c]"
can be achieved with rangeOfString()
with the .CaseInsensitiveSearch
option:
let searchText = "MITH"
let filtered = nameList.filter {
return $0["firstName"]?.rangeOfString(searchText, options: .CaseInsensitiveSearch) != nil
}
// Result: [[firstName: Smith, lastName: Green]]
Swift 3:
let filtered = nameList.filter {
return $0["firstName"]?.range(of: searchText, options: .caseInsensitive) != nil
}
Upvotes: 16
Reputation: 33
You can filter by defining a function to filter by first, or just include the filter in a closure. Here's an excerpt that you can paste into a playground that demonstrates both options:
let nameList : [Dictionary<String,String>] =
[["firstName" : "John Sam","lastName" : "Smith"],
["firstName" : "Johnny","lastName" : "Smith"],
["firstName" : "Albert","lastName" : "Smith"],
["firstName" : "Alby","lastName" : "Wright"],
["firstName" : "Smith","lastName" : "Green"]]
func fn (x: Dictionary<String,String>) -> Bool {
return x["firstName"] == "Johnny"
}
nameList.filter(fn)
var r = nameList.filter({$0["firstName"] == "Johnny"})
r
var s = nameList.filter({$0["lastName"] == "Smith"})
s
You can also filter the results of a filter to search for first and last name, e.g.
var result = (nameList.filter({$0["lastName"] == "Smith"})).filter({$0["firstName"] == "Johnny"})
See also: http://locomoviles.com/ios-tutorials/filtering-swift-array-dictionaries-object-property/
Upvotes: 1
Reputation: 109
Try,
let searchText = "John Sam"
func isMatch (nameDictionary: Dictionary<String, String>) -> Bool {
if(nameDictionary["firstName"] == searchText) {
return true
}
else {
return false
}
}
let results = nameList.filter(isMatch)
You are free to use closure.
let searchText = "John Sam"
let results = nameList.filter {
nameDictionary in
nameDictionary["firstName"] == searchText
}
or,
let searchText = "John Sam"
let results = nameList.filter {
$0["firstName"] == searchText
}
Upvotes: 0
Reputation: 3283
Please try with following way.
I have passed constant value
you need to pass your dynamic value
at place of someString variable
.
let someString = "Alby"
var arr:NSArray =
[["firstName" : "John Sam","lastName" : "Smith"],
["firstName" : "Johnny","lastName" : "Smith"],
["firstName" : "Albert","lastName" : "Smith"],
["firstName" : "Alby","lastName" : "Wright"],
["firstName" : "Smith","lastName" : "Green"]]
var pre:NSPredicate = NSPredicate(format: "firstName CONTAINS[c] %@", someString)!
var result:NSArray = arr.filteredArrayUsingPredicate(pre)
print(result)
Upvotes: 0