在NSArray中搜索值匹配值

Jon*_*an. 22 iphone objective-c nsarray ipad

我有一个NSArray objects,它有一个特殊的属性叫name(类型NSString).
我有第二个NSStrings的NSArray names.

我想获得一个NSArray所有objects.name属性相匹配的一个names第二NSArray的.

我如何快速有效地解决这个问题,因为这将经常需要.

Luk*_*asz 72

为什么不只是使用谓词来为你做这件事?

// For number kind of values:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF = %@", value];
NSArray *results = [array_to_search filteredArrayUsingPredicate:predicate];

// For string kind of values:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF contains[cd] %@", value];
NSArray *results = [array_to_search filteredArrayUsingPredicate:predicate];

// For any object kind of value (yes, you can search objects also):
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", value];
NSArray *results = [array_to_search filteredArrayUsingPredicate:predicate];
Run Code Online (Sandbox Code Playgroud)

  • 为此+1。谓词现在还具有更方便的“predicateWithBlock”。 (2认同)

Ben*_*tto 14

使用您当前的数据结构,您只能在O(n ^ 2)时间内通过为第二个数组的每个成员循环一次第一个数组来执行此操作:

NSMutableArray * array = [NSMutableArray array];
for (NSString * name in names) {
    for (MyObject * object in objects) {
        if ([[myObject name] isEqualToString:name]) {
            [array addObject:object];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

(如Stefan建议的那样:在对象数组上循环,并询问名称数组是否containsObject:为每个对象的名称.)

但是如果这确实需要更快(实际上取决于数组的大小和执行频率的程度),可以通过引入names将第一个数组映射到其对象的NSDictionary来改进这一点.然后,每个查找都是O(1),总时间是O(n).(你必须保持这个字典始终与对象数组保持同步,这对于合理的访问器来说并不难.这种技术也有一个限制,即name不能在多个对象上出现这种情况.)

获得此结果的另一种方法(并且没有最后一个约束)是为第二个集合使用NSSet,然后containsObject:在名称集上遍历调用的每个对象数组.这种技术是否更好取决于您的两个集合是否大致相同,或者一个是否比另一个大得多.


Ste*_*tto 14

这是一个简单的方法:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@", nameToFind];
[listOfItems filteredArrayUsingPredicate:predicate];
Run Code Online (Sandbox Code Playgroud)


Lir*_*rik 6

我喜欢用这个方法:

NSIndexSet *indexes = [_items indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
   return ((MyObject *)obj).name isEqualToString:name];
}];

if (indexes.count != 0) {
//extract your objects from the indexSet, and do what you like...
}
Run Code Online (Sandbox Code Playgroud)