Решение: Я отметил ответ @BlackRider как правильный, поскольку он является наиболее универсальным, особенно для сложных сравнений, однако есть и другие очень хорошие ответы и комментарии. Я призываю кого-либо с тем же или подобным вопросом рассмотреть их и оценить наилучший курс действий для вашей конкретной ситуации.
В моей ситуации я фактически не использую решение BlackRider в своей реализации. Я решил использовать свое решение (см. Редактировать № 2 ниже) с помощью комментариев @JoshCaswell, а также предложение @voromax indexesOfObjectsWithOptions:passingTest:
из-за того, что мои сравнения очень просты в этой ситуации.
Спасибо всем, кто ответил и дал понять.
Я ищу эффективный способ извлечения объекта из NSArray
на основе свойства этого объекта (в этом случае уникальный идентификатор). В С#.NET с использованием Linq я бы сделал что-то вроде
MyObject obj = myList.Single(o => o.uuid == myUUID);
Мне также интересно, есть ли эффективный способ получить массив объектов, соответствующих неистинному свойству. Опять же, с Linq это выглядело бы как
List<MyObject> objs = myList.Where(o => o.flag == true).ToList();
Конечно, я могу писать циклы, чтобы сделать это, но они не будут повторно использоваться, и я подозрюю их производительность.
Поиск объекта с уникальным идентификатором:
-(MyObject*)findObjectWithUUID:(NSString*)searchUUID{
for (MyObject* obj in _myArray){
if([obj.uuid isEqualToString: searchUUID])
return obj;
}
}
Поиск массива объектов:
-(NSArray*)findObjectsWithFlag:(BOOL)f{
NSMutableArray* arr = [NSMutableArray array];
for (MyObject* obj in _myArray){
if(obj.flag == f)
[arr addObject:obj];
}
return arr;
}
- EDIT -
К счастью, в первой ситуации объект, который я ищу, имеет уникальный идентификатор, и я знаю, что его будет только один. Я придумал решение для реализации isEqual для моего объекта, который будет вызываться indexOfObject:
- (BOOL)isEqual:(id)object{
return [self.uuid isEqualToString: ((MyObject*)object).uuid];
}
И затем создайте "поддельный" объект поиска и используйте это, чтобы найти реальный
MyObject *lookupObject = [[MyObject alloc] init];
lookupObject.uuid = searchUUID;
MyObject *actualObject =
[_myArray objectAtIndex:[_myArray indexOfObject:lookupObject]];
Это по существу то же самое, что и для цикла for-in, который я разместил выше, но может быть более читаемым и быть более многоразовым. Конечно, это работает только для поиска одного уникального объекта и не затрагивает вторую половину моего вопроса.
- EDIT 2 -
Проверка Class
и реализация hash
, как рекомендовано в комментариях.
- (BOOL)isEqual:(id)object{
return [object isKindOfClass:[MyObject class]] &&
[self.uuid isEqualToString: ((MyObject*)object).uuid];
}
- (NSUInteger)hash{
return [self.uuid hash];
}