0

I have an array of objects. The objects in the array contain a dictionary as one of its properties and i need to search the values of one of those keys for each object within the array. I need to use a like condition(I think its actually contains in objective-c I may be wrong though). Im using the method _search_results = [_people filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"details[@\"firstName\"] contains %@",searchBar.text]]; which i think will return me all the objects that fit that search condition. Here are my questions

1) Is there another method I can use to do this? Or maybe a different class all in general? Maybe a more efficient method to use? 2) Am i going about searching for the value correctly within the dictionary? Since its a property of the object i think im doing it right. Which the syntax to me looks correct dictionaryName[keyName] contains value

Ive only use NSPredicate with properties of objects, i never had to search a dictionary thats in an object like this. So like i said I think im right here.

In response to the first set of answers

_search_results = [_people indexesOfObjectsPassingTest:^BOOL(PeopleObject *person, NSUInteger idx, BOOL * _Nonnull stop) {

    NSString *last_name = person.details[kPersonLastNameKey];
    if([last_name containsString:searchBar.text]){
        return TRUE;
    }
    else 
        return FALSE;
}];
2
  • Your use of indexesOfObjectsPassingTest is all mixed up. You don't create an index set. You don't manipulate an index set. You write a block that takes a single object as an input, and returns TRUE if it should be made a member of the set, and FALSE if not. The indexesOfObjectsPassingTest method does the work of creating the index set, then using your block to test each item in the array and returning an index set with the objects that pass your test. Commented Feb 21, 2016 at 22:19
  • Now you've got it. BTW, since there is a back-and-forth discussion, it would be a good idea to show both sets of edits: The mixed-up code as edit #1, and your new, correct code as edit #2, so people reading the discussion don't get confused. Commented Feb 22, 2016 at 1:11

1 Answer 1

1

There are at least a half-dozen ways to do this. You don't say if you're using Objective-C or Swift, although the sample code you show looks like Objective-C.

If you were using Swift you could use the built-in Swift filter function, but let's forgo that.

You could use filteredArrayUsingPredicate, as you're doing now.

You could use indexesOfObjectsPassingTest to build an NSIndexSet of the objects in your array that meet your criteria (That method takes a block, and for all objects where your block returns true, the resulting index set includes the index of the object. You'd then use objectsAtIndexes to return an array of the objects listed in the index set.

I haven't benchmarked it, but I suspect that for large arrays, the predicate method is slower, since predicates are a very flexible method of selecting objects, and flexible code tends to be slower code. However, unless you are filtering tens of thousands of objects, or more, I doubt if you'd even notice the difference in performance.

Don't fall into the trap of premature optimization - wasting your time and making your code more complex to optimize things that do not have a meaningful impact on your app's performance.

Unless your app is running noticeably slowly, and you've tested it and determined that the array filtering has a significant influence on that slowness, it's probably not worth worrying about.

Sign up to request clarification or add additional context in comments.

8 Comments

Well i know theres a bunch of ways thanks for the advice. But i was mostly going for 2 things. 1 Which one was the most efficant? I thought NSPredicate would be since its a 1 liner and 2) I already know my syntax is incorrect for me predicate parsing string. What is the correct syntax for searching a dictionary that is a property of a class? Honestly thought i cant see this list going more than 100 people. So i think NSPredicate is the way to go no?
Thanks for the quick response also
I don't use predicates very often, so I can't tell you the correct syntax off the top of my head. I'd have to do some digging. (As a result of not knowing them super-well, I'm more apt to use a code-based approach like indexesOfObjectsPassingTest, or better yet the Swift filter statement, which is taylor-made for this situation.)
As for efficiency, for an array of 100 items, it doesn't matter. You would be hard-pressed to detect the difference in performance between the different methods you might use. It's only when you're dealing with many thousands of items that performance becomes an issue.
I actually just modified my question to fit the answers you gave me but i think im doing it incorrectly. Since i should just be able to set an NSIndexSet object to the result of the block. I just dont understand how to execute the block because according to the docs if i set the return value to TRUE it stops the block from continuing. I dont want that. So I know its correct now, but how am i supposed to check the condition if i cant set the return value to TRUE? Im kinda confused on that part.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.