1

Does the IN operator work for filtering SBElementArrays? I have been trying to use it but it always returns a NULL array.

My code (hexArray will typically have more elements):

SBElementArray *musicTracks = [libraryPlaylist fileTracks];
hexArray = [NSArray arrayWithObject: @"3802BF81BD1DAB10"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY %K IN %@",@"persistentID",hexArray];

NSLog(@"%@", [[musicTracks filteredArrayUsingPredicate:predicate] valueForKey:@"persistentID"]);
NSLog(@"%@", hexArray);
NSLog(@"%@", predicate);

Output:

2013-05-26 12:59:29.907 test[1226:403] (null)
2013-05-26 12:59:29.907 test[1226:403] (3802BF81BD1DAB10)
2013-05-26 12:59:29.908 test[1226:403] ANY persistentID IN {"3802BF81BD1DAB10"}

I have tried setting the predicate to:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY %K == %@",@"persistentID",hexArray];

Output:

2013-05-26 13:03:04.629 test[1258:403] (3802BF81BD1DAB10)
2013-05-26 13:03:04.630 test[1258:403] (3802BF81BD1DAB10)
2013-05-26 13:03:04.630 test[1258:403] ANY persistentID == {"3802BF81BD1DAB10"}

And this works fine. But I would like the IN functionality.

abroekhof
  • 796
  • 1
  • 7
  • 20
  • Without having tried this, my guess is that the `SBObjects` in the `SBElementArray` are not key-value-coding compliant for the `persistentID` key. – Dave DeLong May 26 '13 at 13:14

5 Answers5

2

Instead of doing

persistentID IN ('abc', 'abc', 'abc', ...)

you can do

persistentID == 'abc' OR persistentID == 'abc' OR ...

It seems to work pretty fast.


NSMutableArray *subPredicates = [NSMutableArray arrayWithCapacity:persistentIDs.count];

for (NSNumber *persistentID in persistentIDs) {
    [subPredicates addObject:pred(@"persistentID == %@", persistentID.hexValue)];
}

NSPredicate *predicate = [NSCompoundPredicate orPredicateWithSubpredicates:subPredicates];
[tracks filterUsingPredicate:predicate];

NSLog(@"%ld", tracks.count);
IluTov
  • 6,807
  • 6
  • 41
  • 103
0

Try using CONTAINS[c]

Ex:-

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY %@ CONTAINS[c] %k",hexArray, @"persistentID"];
Burhanuddin Sunelwala
  • 5,318
  • 3
  • 25
  • 51
0

I ended up just looping through all the elements of hexArray and using an equality predicate on each pass. Probably not the most efficient, but it works.

for (NSString *hexID in hexArray){
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"persistentID == %@",hexID];
        iTunesTrack *track = [[musicTracks filteredArrayUsingPredicate:predicate] objectAtIndex:0];
        [track duplicateTo:playlist];
    }
abroekhof
  • 796
  • 1
  • 7
  • 20
0

Your predicate should be %K IN %@ (without the ANY), if I understand your intention correctly (get all the tracks that have one of the IDs in the array).

For some reason, this doesn't work with SBElementArray, but you could simply convert it to a regular NSArray before applying the predicate (an NSSet should work too, and might be more efficient):

SBElementArray *musicTracks = [libraryPlaylist fileTracks];
NSArray *musicTracksArray = [NSArray arrayWithArray:musicTracks];

NSArray *hexArray = [NSArray arrayWithObjects: @"CE24B292556DB1BA", @"CE24B292556DB1F0", @"CE24B292556DB1C4", nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K IN %@", @"persistentID", hexArray];
NSLog(@"%@", [[musicTracksArray filteredArrayUsingPredicate:predicate] valueForKey:@"persistentID"]);
omz
  • 53,243
  • 5
  • 129
  • 141
0

Scripting Bridge technically supports the IN operator, in that it will construct a properly-formed Apple event for it, but most applications don't understand it. The best workaround is the chained OR tests as suggested by NSAddict.

Chris N
  • 905
  • 5
  • 10