How to search particular contact from nsarray of nsarray - ios

I have store the contact in alphabetical order so I have array of array for contact list which i have display on screen. Now i want to search the contact via name but predicate not work properly here. I have done below code.
filterArray.filterUsingPredicate(NSPredicate(format: "ANY SELF.name CONTAINS[cd] '\(tfSearchBar.text!)'", argumentArray: nil))
In filter array first i have all contact but when i search for "a" it gives all the section array which has "a" in the contact name. but here i have stuck. It is not necessary that the all contact of the section contain "a" in the contact name.
For example
(
A:(
{
name = "abc"
number = "123456"
}
{
name = "azx"
number = "123456"
}
)
)
For example for above example after search for "a". when i search for "ab" then same array return by predicate.Not only first object. Any way to find only first object with out nested predicate.

I'm not sure what you are trying to accomplish with the word "ANY" in your predicate but it seems redundant. This code works as you describe when put into a Playground:
import UIKit
#objc class DataElement : NSObject {
let name : String
let number : String
init(name : String, number : String) {
self.name = name
self.number = number
}
}
let dataArray : NSArray = [
DataElement(name: "abc", number: "123456"),
DataElement(name: "azx", number: "689101")
]
let searchTerm = "a"
let predicate = NSPredicate(format: "SELF.name CONTAINS[cd] '\(searchTerm)'", argumentArray: nil)
dataArray.filteredArrayUsingPredicate(predicate)

Related

Create NSPredicate with ANY and two conditions for it

I simply have two entities: Product and Item. Product may have many items: Set<Item>. Item has two properties: isActive and identifier.
Now I need to fetch all Products which have at least one Item with the following conditions met the same time:
identifier IN %# //["1", "2"]
isActive = true
let format = "ANY (items.identifier IN %# AND items.isActive = true)"
let predicate = NSPredicate(format: format, ["1", "2"])
But I got exception: Unable to parse the format ...
Why?
You can try this -
let format = "SUBQUERY(items, $item, $item.identifier IN %# AND $item.isActive = true).#count > 0"
let predicate = NSPredicate(format: format, ["1", "2"])
Source : NSPredicate Cheatsheet

Swift - Predicate to filter an array by a property of member array

I need to filter out an array of MyClass3 Objects. An array of MyClass2 Objects is a member of MyClass3 object(Please refer to code below). MyClass2 object has an id. I have an idArray at hand. I need to filter out those MyClass3 objects in which all ids in idArray are present in its [MyClass2] member.
class MyClass2 : NSObject {
var uid: Int = 0
init(uid : Int) {
self.uid = uid
}
}
class MyClass3 : NSObject {
var arr: [MyClass2]
init(units: [MyClass2]) {
arr = units
}
}
var units1 = [MyClass2(uid: 1),MyClass2(uid: 2), MyClass2(uid: 3), MyClass2(uid: 4), MyClass2(uid: 5)]
var units2 = [MyClass2(uid: 4),MyClass2(uid: 5), MyClass2(uid: 6)]
var units3 = [MyClass2(uid: 3),MyClass2(uid: 5), MyClass2(uid: 7), MyClass2(uid: 1)]
var ids = [1,5]
var available3: [MyClass3] = [MyClass3(units: units1), MyClass3(units: units2), MyClass3(units: units3)]
var filtered3: [MyClass3] = []
let searchPredicate: NSPredicate = NSPredicate(format: " ANY arr.uid IN \(ids)") // needed predicate
print(searchPredicate.predicateFormat)
filtered3 = (available3 as NSArray).filteredArrayUsingPredicate(searchPredicate) as! [MyClass3]
The required answer is that we need MyClass3(units: units1) and MyClass3(units: units3) in the filtered Array.
This is not working out. Can someone suggest a predicate format for this purpose
Using string interpolation in predicate format strings is never a good
idea. The correct form of your predicate would be
let searchPredicate = NSPredicate(format: "ANY arr.uid IN %#", ids)
However that checks if any of the uids is in the given list.
To check if all uids are in the given list, the following predicate
should work:
let searchPredicate = NSPredicate(format: "SUBQUERY(arr.uid, $x, $x IN %#).#count = %d", ids, ids.count)
The same can be achieved without predicates in "pure" Swift 3 as
filtered3 = available3.filter { $0.arr.filter { ids.contains($0.uid) }.count == ids.count }
or
filtered3 = available3.filter { Set(ids).isSubset(of: $0.arr.map { $0.uid }) }
You can do using perform intersection operation instead of NSPredicate:
Refer below link for this
Set operations (union, intersection) on Swift array?
You can check out this link for good examples but for filtering of arrays you can use something like :
filteredArray = wholeArray.filter{ !unwantedArray.contains($0)}

How to sort Core Data using the last name, with only a full name available?

I have a fullName property in my Core Data entity Friends, which has values like:
John Doe
Jane Smith
Joe Bloggs
I want to be able to extract the last name, and sort using these alphabetically, in Swift.
I currently only know how to sort using the full name, like so:
let sortDescriptor = NSSortDescriptor(key: "fullName", ascending: true)
request.sortDescriptors = [sortDescriptor]
Thanks.
You can do as Follow.
1) Fetch all record from core data. (Suppose You have get aryFullname)
2) Using for loop you can get array only last name as follow.
//Define new mutable array aryfinalData
for i in 0..<aryFullname.count
{
var fullName = aryFullname.ObjectAtindex(i)
var fullNameArr = split(fullName) {$0 == " "}
var lastName: String? = fullNameArr.count > 1 ? fullNameArr[1] : nil
aryfinalData.addObject(lastName)
}
3) Sort Array as follow.
// convert NSMutableArray to the Array by using below line of code.
let arySort = aryfinalData as AnyObject as! [String]
var sortedArray = arySort.sort { $0.name < $1.name }
// sortedArray is your Final array
Note: This is not a efficient solution but you don't have any solution and I am not sure about the above syntax so take care for the same and do changes if any require.

How to search from array of SwiftyJSON objects?

I have an SwiftyJSON object.
How to search by key(name) from the array of SwiftyJSON object.
For Example :
let arrCountry = [JSON]()
Now one country array contains
{
countryid : "1"
name : "New York"
},
{
countryid : "2"
name : "Sydeny"
}
How to search by predicate or something?
If I search "y" from the array then it should return both object (Because both contains "y") in another JSON array. And If I type "Syd" then it should return only one object in JSON array. As LIKE query in SQL. And as we are doing with predicates...
Get the array from the JSON object with arrayObject, cast it to the proper type and apply the filter function, in this example to find the item whose name is def
if let array = arrCountry.arrayObject as? [[String:String]],
foundItem = array.first(where: { $0["name"] == "def"}) {
print(foundItem)
}
Edit: For a refined search with NSPredicate and a JSON result use this
let searchText = "y"
let searchPredicate = NSPredicate(format: "name contains[cd] %#", searchText)
if let array = arrCountry.arrayObject as? [[String:String]] {
let foundItems = JSON(array.filter{ searchPredicate.evaluateWithObject($0) })
print(foundItems)
}
You need to extract the dictionary Array from the JSON Object and the you can apply the Predicate to that array.

Using NSPredicate with array for cloudKit search

When using a NSPredicate, I'm trying to search all objects (strings) contained within an array. The code sample below works but the predicate only collects the object in the first index only?? The NSPredicate is used for a CKQueryOperation.
Each Record has a value for a key named Category.
let array: [String] = ["Education", "Sport", "TV and Film"]
// select all records
//let predicate = NSPredicate(format: "Category = %#", category )
let predicate = NSPredicate (format: "Category == %#", argumentArray: array)
let query = CKQuery(recordType: "quizRecord", predicate: predicate)
// get just one value only
let operation = CKQueryOperation(query: query)
//code works but only queries Records with the Category for "Education"
Try replacing:
"Category == %#"
With:
"Category IN %#"
I was having the same issue as Peter Wiley. The solution I found was a mash up of Danny Bravo's solution and comment on that solution.
let arrayPredicate = NSPredicate(format: "Name IN %#", argumentArray: [names])
To get multiple results I needed to use both the keyword "IN" in the format and wrap my argumentArray with [].

Resources