2

In short, I am looking for the correct predicate format to index into a dictionary attribute on an object.

I have an array of myObject instances, each with an attribute CPDictionary(NSMutableDictionary) extAttributes and I am trying to allow filtering based on values in extAttributes. I am defining my predicate as follows

[CPPredicate predicateWithFormat:@"extAttributes[%K] like[c] %@",key,val]

I am not sure what the correct key-path would be for this. Reading the documentation on NSPredicate it would seem that "extAttributes[%k]" might be an index into an array, not a dictionary. I have tried several alternatives and this is the only one that doesn't error. When inspecting the resulting objects, the expressions in the predicate object appear to be correct. However, it doesn't have the intended result.

Ivan Chaer
  • 6,980
  • 1
  • 38
  • 48
jlujan
  • 1,188
  • 7
  • 10
  • I solved this by implementing `-(id)valueForUndefinedKey:(id)key` on myObject. ` -(id)valueForUndefinedKey:(id)key { ret = [extAttributes objectForKey:key]; return ret; } ` Then it is just `[CPPredicate predicateWithFormat:@"%K like[c] %@",key,val];` – jlujan Sep 22 '11 at 18:52
  • That's a hack. Don't do that. Use a key path. – jlehr Sep 22 '11 at 18:52
  • It was a side effect of it already being implemented to add random columns to a table view. What would the correct key-path be? – jlujan Sep 22 '11 at 19:42

1 Answers1

3

It looks like you might be confusing array and dictionary references. Just use a key path (dot-separated element names) to refer to nested elements or object properties, conceptually something like this:

[CPPredicate predicateWithFormat:@"%K like[c] %@", @"extAttributes.myNestedElementName", val];

Then again, I'm not all that familiar with Cappuccino, so I'm not sure if they've done something slightly different here, but this is the way it works in Cocoa and Cocoa touch.

EDIT

To compute the key dynamically, all you need to do is compose a key path string:

 var keyPath = [CPString stringWithFormat:@"%@.%@", @"extAttributes", key];

You can now create the predicate as follows:

[CPPredicate predicateWithFormat:@"%K like[c] %@", keyPath, val];

EDIT

The equivalent code in Cocoa/Cocoa touch would be:

NSString *keyPath = [NSString stringWithFormat:@"%@.%@", @"extAttributes", key];
[NSPredicate predicateWithFormat:@"%K like[c] %@", keyPath, val];
jlehr
  • 15,557
  • 5
  • 43
  • 45
  • Thanks, but I do not think this will do what I entend either. I am not sure what `myNestedElementName` is in your example or I might be misunderstanding. `[[myObject extAttributes] objectForKey:key]` would be normal use. I have tried `[CPPredicate predicateWithFormat:@"extAttributes.%K like[c] %@", key, val];` which does not work either. – jlujan Sep 22 '11 at 18:45
  • 1
    I'll add some additional details to my answer to clarify. – jlehr Sep 22 '11 at 20:39
  • Just for other readers who find this later: in Cappuccino, replace `NSString *` with `var ` and `NSString` with `CPString`. – Alexander Ljungberg Sep 23 '11 at 11:21