Core data to-many NSPredicate with AND - cocoa

I'm trying to write a query for the find-as-you-type search bar. What I want to do is query "Kind", and return any Kinds for which there is a LocalName with ('name' LIKE %# AND localeIdentifier == %#).
If I'm only searching the names (so ignoring the localeIdentifier), I could do something like this:
ANY localized.name LIKE %#
What I want is something more like
ANY localized.(name LIKE %# AND localeIdentifier == %#)
To sum up, searching "Kind", any one item in the to-many relationship "localized" should match both name and localeIdentifier.
Any ideas for the correct syntax of this?

What you want is a subquery. In predicate format syntax:
SUBQUERY(self.localized, $x, $x.name LIKE %# AND $x.localeIdentifier == %#).#count > 0
where the SUBQUERY expression returns a collection of instances in the self.localized collection that match the predicate in the third argument. Kind instances for which this SUBQUERY expression is non-empty (ie #count > 0) match your desired criteria.
The SUBQUERY expression was introduced in OS X 10.5.

Related

LINQ query to find items where multiple substrings are searched on one column

Select * from web_data where Title like "%Lawn%" || Title like "%silk%"......and so on.
Lawn, Silk etc are in List<web_data>. So i'm looking for a way to search those substrings in the Title column(discription property). One of them must be contained, then the row should be returned.
I've tried this
query = query
.Where(x => filter.FabricType.Any(f => x.discription.Contains(x.discription)))
.AsQueryable();
It's not working. That linq to sql code returns an error:
Local sequence cannot be used in LINQ to SQL implementations of query operators except the Contains operator.
any alternatives?
You can use Contains() or You can also use .StartsWith() or .EndsWith().
collListItem.Where(x => x.discription.Contains("Lawn") || x.discription.Contains("silk")).ToList();

CloudKit Query: After Date and Not in Array

I'm trying to query records from CloudKit that either have a newer modificationDate than what I have locally, or perhaps that I don't have at all.
The records I have already are stored in recordNames. The the date is date.
I can do this with two predicates like this:
//Modification Date
let predicateDate = NSPredicate(format: "modificationDate > %#", date)
//Records I have already
let predicateRecordName = NSPredicate(format: "NOT (recordName IN %#)",recordNames)
//Combined 'OR'
let predicate = NSCompoundPredicate(orPredicateWithSubpredicates: [predicateDate, predicateRecordName])
But when I try to combine this as a compound OR predicate, or combine them into a single predicate, I get an error:
Invalid predicate... CKErrorDomain Code=12... is not a comparison predicate, ck_isComparisonError=true
I see in the docs that doing an OR predicate is not allowed. I'd love to not have to make two separate queries here. Any ideas on how I can pull this off?
'OR' option not working with predicates (I don't know if this is a bug of CloudKit). You have to make multiple queries.

Groovy Sql rows

Hello I am trying to get rows using Groovy Sql connection but it returns me records as a List inside a List. The following:
Sql sql = new Sql(dataSource)
List<GroovyRowResult> row = sql.rows('select * from user where username=:userName and password=:password, [userName:'groovy',password:'123'])
returns the result as [[return record as map]]
Any one help me to figure out why the result is a List inside a List. How will I get it as a single level List using the rows method?
Your results are coming back as a list of maps, not a list of lists. Look at the ':' and ',' chars in the inner part. You can use standard groovy extraction of values from these.
In your case, it looks like you're using a primary key search, so will only return one result, so use firstRow in this case, so that you don't have to extract the single map result from the list.
See the documentation for the groovy Sql class for examples.
In the more general case where you are returning multiple rows, then your data probably looks like this:
[[username:"foo", password:"foopass"], [username:"bar", password:"barpass"]]
Assuming the line:
def results = sql.rows('select * from user')
You can then do things like spread operators:
assert results.username == ["foo", "bar"]
assert results.password == ["foopass", "barpass"]
or iterate over the results
results.each { println it.username }
==> foo
==> bar
or use any of the many Collection functions
println results.collect { "${it.username} -> ${it.password}" }
==> [ "foo -> foopass", "bar -> barpass" ]
I think your main issue was not recognising a single map entry in a list.
It doesn't return a List inside a List, it returns a List of Map with each map containing the columns selected from your select.
So if you want all of the usernames selected (as a List), you can just do:
def usernames = row.username
If you just want a single row, you can do:
GroovyRowResult row = sql.firstRow('select * from user where username=:userName and password=:password, [userName:'groovy',password:'123'])
And then this will effectively just be a map with each key being the field name selected, and each value being the value of the first row of each field

Cocoa - Filter an Array NSDictionary on a tableview

I've a tableview that has an array of dictionaries datasource. Now I want to do a filter inside this table, but I want to be able to filter for 5 different fields, like name, number, email, etc.
How can I do it? I've found a way to do it in a Array, but I can't figure how to make it on a dicionary.
If you want to filter an array of dictionaries, just use filteredArrayUsingPredicate: something like this:
NSPredicate *pred = [NSPredicate predicateWithFormat:#"SELF.name = %#",#"Fabio"];
NSArray *filtered = [myArray filteredArrayUsingPredicate:pred];
This will give you an array where all the dictionaries will have the name value of Fabio.
After Edit: if you want to do a broader search you could add an "OR" in the predicate like this:
NSPredicate *pred = [NSPredicate predicateWithFormat:#"SELF.name = %# OR SELF.email BEGINSWITH[c] %#",#"Fabio",#"fabio"];
This would give you any dictionaries where the name is Fabio, or the email starts with fabio (or Fabio, the [c] parameter means it will match either capitalized or not).
Use NSPredicateFilter based on which column you clicked.

How do I filter in linq query when field needs parsing first?

I have a data table containing multiple columns and one column that stores somewhat complex text patterns - I need to parse the field to determine if a particular sub strings exist in specific positions within the larger string pattern and then if the record should be filtered out as a result.
I can't see a way to perform the parse other than by writing a C# parsing function with String.Split method calls, foreach, etc. But if I try to parse like this:
var myFilteredTable = _db.MyTable.Where(t => t.Column1 == 'Filter1'
&& ParseIsMyItemInColumn2(t) );
I get "has no supported translation to SQL" errors.
The other option I thought of was to build the initial result without the Parse:
var myFilteredTable = _db.MyTable.Where(t => t.Column1 == 'Filter1' );
and iterate through the IQueryable resultset, testing each row with the parse function, to filter out the unwanted rows, but IQueryable does not have Remove function to strip out unwanted rows nor Add function to allow me to build up a new resultset.
So how can I filter in linq when I also need to write a Parse function?
Well the "initial filter in the database then do the rest locally" is easy:
var filtered = _db.MyTable.Where(t => t.Column1 == "Filter1")
.AsEnumerable() // Do the rest locally
.Where(t => ParseIsMyItemInColumn2(t));
AsEnumerable is a simple pass through method, but because the result is typed as IEnumerable<T> rather than IQueryable<T>, the subsequent LINQ operations use the LINQ to Objects methods in Enumerable rather than the ones in Queryable.
Obviously if a lot of items match the first filter but fail the second, that won't be terribly efficient...
Unfortunately, if the "parse function" is not something that can be translated to SQL, you will need to pull the results and use LINQ to Objects:
var myFilteredTable = _db.MyTable.Where(t => t.Column1 == 'Filter1')
.AsEnumerable().Where(ParseIsMyItemInColumn2);
Note that this will stream all of the results into memory, and then perform your parse.

Resources