This question is based off of the same app/source from my previous question which can be found here:
How to manage memory using classes in Objective-C?
I have a nested array which looks something like this when printed out (I only copied and pasted a brief part of it).
(
(
<Term: 0x4256420>,
<Term: 0x420fa40>,
<Term: 0x4257bd0>,
<Term: 0x4257cf0>,
<Term: 0x4257d90>,
<Term: 0x4257e30>
),
(
<Term: 0x4257e50>,
<Term: 0x4257f90>,
<Term: 0x4257fb0>,
<Term: 0x42580e0>,
<Term: 0x4258170>,
<Term: 0x4258210>,
<Term: 0x4258230>,
<Term: 0x4258360>,
<Term: 0x4258400>,
<Term: 0x42584a0>,
<Term: 0x4258540>,
<Term: 0x42585e0>,
<Term: 0x4258670>,
<Term: 0x4258710>
),
And here is my code for the search part of my table:
- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section
{
// Normal table
if (aTableView == self.tableView) return [[self.sectionArray objectAtIndex:section] count];
// Search table
//NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name contains[cd] %@", self.searchBar.text];
//self.filteredArray = [self.crayonColors filteredArrayUsingPredicate:predicate];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name contains[cd] %@", self.searchBar.text];
self.filteredArray = [[self.sectionArray objectAtIndex:section] filteredArrayUsingPredicate:predicate];
return self.filteredArray.count;
}
I am getting the error that I cannot allocate enough room which means that I must be doing something wrong, I just cannot figure out what.
The commented out portion of the search part in the above method works but crayonColors is just a simple NSMutableDictionary of NSStrings and does not have arrays nested inside of it.
Thanks in advance!
As far as I'm aware, you can't do this with a single predicate. However, you can do it with a key-path operator and a predicate in two separate calls.
So, you have an array of arrays of terms. You want a single array of terms where its name contains 'A' (for example). Here's what you do:
NSArray * allTerms = ...; //your array of arrays of terms
NSArray * collapsedTerms = [allTerms valueForKeyPath:@"@unionOfArrays.self"];
NSPredicate * filter = [NSPredicate predicateWithFormat:@"name CONTAINS[cd] %@", @"A"];
NSArray * filteredTerms = [collapsedTerms filteredArrayUsingPredicate:filter];
The magic here is the valueForKeyPath:
bit. The @unionOfArrays
operator takes an array of arrays of objects, and returns an array of objects. Here's what it's doing: The NSArray
is going to break the keypath up by .
, giving it @unionOfArrays
and self
. It's going to recurse and invoke valueForKeyPath:
on itself using the second bit (self), and it's going to get back an array of arrays. It's then going to mash all those arrays together into a single array, ignoring duplicates. (If you want to remove duplicates, use @distinctUnionOfArrays
instead)
Once we have that array of objects, we can then filter it normally using a simple name CONTAINS 'blah'
predicate.
(I thought I might be able to get this to work using a SUBQUERY
, but that's a strange beast and nothing was immediately obvious to me.)
For the super intrepid, you could do this with a single method call using KickingBear's collection extensions ( available here ), but I would strongly advise against using hacks like that in a production setting. :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.