Reputation: 6082
I'm new to Swift language so playing with Playground.
As my title saying what is the best way to search result from the array of the dictionary?
Ex.
Below is my Array I created for learning purpose.
let array = [
["name": "Amit", "age": "27", "rollno": 12],
["name": "Ananad", "age": "26", "rollno": 10],
["name": "Kashyap", "age": "25", "rollno": 11],
["name": "Raj", "age": "25", "rollno": 07],
["name": "Akshya", "age": "28", "rollno": 13]
]
And I want to search "name" based on user input. Look at below stuff what I have done.
let strSeach = "k"
let searchResult = myArray.filter{String(($0["name"] as! String).characters.prefix(strSeach.characters.count)).lowercased() == strSeach.lowercased()}
print("index => \(searchResult)")
Output is:
searchResult => [["rollno": 11, "name": "Kashyap", "age": "25"]]
But confusion, Is it right way to search? I used characters.prefix
, lowercased()
is it good or another best way?
and If I want to apply multiple searches like search by "name", "age" etc. then how can we achieve it in swift filter?
I think we can't use NSPredicate
with Swift Array
? otherwise, we can do it by following
let searchPredicate = NSPredicate(format: "name CONTAINS [c] %@ OR age CONTAINS [c]", strSeach)
Like that!
Upvotes: 0
Views: 111
Reputation: 59496
First of all you should define the following Model Value to represent your data
struct Person {
let name: String
let age: Int
let rollno: Int
init?(dict:[String:Any]) {
guard
let name = dict["name"] as? String,
let ageText = dict["age"] as? String,
let age = Int(ageText),
let rollno = dict["rollno"] as? Int
else { return nil}
self.name = name
self.age = age
self.rollno = rollno
}
}
Now, given your initial array
let data = [
["name": "Amit", "age": "27", "rollno": 12],
["name": "Ananad", "age": "26", "rollno": 10],
["name": "Kashyap", "age": "25", "rollno": 11],
["name": "Raj", "age": "25", "rollno": 07],
["name": "Akshya", "age": "28", "rollno": 13]
]
you can get an array of Person(s)
let persons = data.flatMap(Person.init)
Now the filtering part is trivial, look
let personsWhereNameContainsK = persons.filter { $0.name.lowercased().contains("k") }
Result
[
Person(name: "Kashyap", age: 25, rollno: 11),
Person(name: "Akshya", age: 28, rollno: 13)
]
Upvotes: 1
Reputation: 16436
With Filters
You can use this
let array = [
["name": "Amit", "age": "27", "rollno": 12],
["name": "Ananad", "age": "26", "rollno": 10],
["name": "Kashyap", "age": "25", "rollno": 11],
["name": "Raj", "age": "25", "rollno": 07],
["name": "Akshya", "age": "28", "rollno": 13]
]
let searchSting = "am"
var search = array.filter { ($0["name"] as! String).lowercased().contains(searchSting.lowercased()) }
Output
[["rollno": 12, "name": "Amit", "age": "27"]]
WITH Predicates
let searchPredicate = NSPredicate(format: "name CONTAINS [c] %@ OR age == %@", searchSting)
search = array.filter { searchPredicate.evaluate(with: $0)}
OUTPUT
[["rollno": 12, "name": "Amit", "age": "27"]]
Upvotes: 1
Reputation: 271050
You can use NSPredicate
if you want, but note that it is slower than filter
.
You just need to convert your swift array to an NSArray
then call filtered
.
Also, here's another way of doing this using swift filter:
let searchResult = array.filter {
($0["name"] as! String).lowercased().hasPrefix(strSeach.lowercased()) }
Upvotes: 1
Reputation: 5955
You can use contains
keyword in the filter as follows,
let searchResult = myArray.filter{String(($0["name"] as! String).lowercased().contains(strSeach.lowercased())}
For Multiple filters (i am adding condition based on your predicate),
let searchResult = myArray.filter{(String(($0["name"] as! String).lowercased().contains(strSeach.lowercased())) || (String(($0["age"] as! String).lowercased().contains(strSeach.lowercased()))}
Upvotes: 0