IOS - Поиск сложного объекта в массиве
У меня есть объект из класса NSObject, который я называю "брендом", и имеет следующие свойства:
.name
.number
.site
в данный момент, десятки этих объектов хранятся в NSMutableArray, что-то вроде:
object 1
object 2
object 3
object 4
...
Я хотел бы иметь возможность получить заданный объект из массива по его числу. Не индекс объекта в массиве, а свойство number объекта (получить объект
который имеет свойство числа, равное 10, например).
Я знаю, что у NSArrays есть умные методы для извлечения данных, но я не знаю их глубоко, потому что редко использую это. Есть ли способ получить этот объект из массива без необходимости повторять все объекты в массиве и проверить свойство каждого номера объекта?
Можете ли вы, ребята, помочь? спасибо.
Ответы
Ответ 1
Я бы порекомендовал NSPredicate
. Вы могли бы сделать это примерно так, предполагая, что listOfItems
- это ваш массив, содержащий ваш NSObject
с указанными свойствами.
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"number == 10"];
NSArray *filtered = [listOfItems filteredArrayUsingPredicate:predicate];
Отфильтрованные результаты, любые числа, соответствующие 10
, теперь будут в массиве filtered
. Если вы хотите вернуть свой объект, вы можете сделать что-то вроде этого:
YourObject *object = (YourObject*)[filtered objectAtIndex:0];
Надеюсь, что это поможет.
Ответ 2
NSUInteger indexOfObject10 = [myArray indexOfObjectPassingTest:^(id obj, NSUInteger idx, BOOL *stop){
MyObject *object = (MyObject *)obj;
return [object.number == 10];
}];
MyObject *object10 = myArray[indexOfObject10];
Ответ 3
Я предпочитаю использовать расширения блока NSArray, которые позволяют вам "говорить" с ними более естественно и писать меньше кода. Что-то в строках жаргонов Smalltalk Collections:
- обнаружение:
- выберите:
- введите:
- и др.
В вашем случае я бы использовал:
MyObject* theObject = [myArray detect:^(MyObject* each){
return each.number == 10;
}];
Здесь у вас есть возможная реализация для этого расширения для NSArray
typedef BOOL (^BlockPredicate) (id element);
-(id) detect:(BlockPredicate) predicateBlock{
for (id each in self) {
if (predicateBlock(each)) {
return each;
}
}
return nil;
}
Я считаю, что такие инструменты действительно полезны. Надеюсь, вы найдете их полезными.
Ответ 4
Возможно, что-то вроде этого:
NSObject *retrieveObject = [[NSObject alloc] init];
retrieveObject.number = 1;
NSObject *anObject = [yourMutableArray objectAtIndex:[yourMutableArray indexOfObjectIdenticalTo:testObject]];
Сначала я создаю объект с тем же номером, что и объект в массиве, который я хочу получить (в данном случае "1" ). В следующей строке я предполагаю, что когда вы ее извлекаете, вы хотите присвоить это значение другому объекту, поэтому я получаю его с помощью стандартного метода objectAtIndex:
с параметром индекса, являющимся другим методом, методом indexOfObjectIdenticalTo:
, с этим параметр метода является объектом retriveObject
. Итак, что это такое, это выглядит в массиве для первого объекта, идентичного retrieveObject (что означает, что у них будет одинаковое число) и возвращает этот индекс объекта, а затем передает это значение в метод objectAtIndex
.
Надеюсь, это поможет!