Как отфильтровать массив с помощью массива?

У меня есть три типа пользовательских классов (см. ниже) и три массива: componentList, componentGroupList и componentGroupItemList. Массивы не связаны, каждый из них содержит все объекты. Мне нужно отфильтровать определенный компонент, все связанные с ним группы и все связанные с ними элементы.

Теперь я знаю, как отфильтровать componentList с помощью @"componentId==123" и получить желаемый объект компонента. Я также могу отфильтровать его группы из componentGroupList, используя тот же предикат, потому что объект ComponentGroup содержит тот же ключ componentId. Однако я не знаю, как отфильтровать связанные объекты ComponentGroupItem из componentGroupItemList.

В настоящее время у меня есть отфильтрованный массив, содержащий объекты ComponentGroup, и я хотел бы отфильтровать componentGroupItemList, используя этот массив. Возможно ли это, или мне нужно извлечь все значения «groupId» из filteredComponentGroupList в строку, а затем сделать какой-то предикат?

Классы:

@interface Component : NSObject

  @property (nonatomic, strong) NSNumber *componentId;
  @property (nonatomic, strong) NSString *title;

@end

@interface ComponentGroup : NSObject

  @property (nonatomic, strong) NSNumber *groupId;
  @property (nonatomic, strong) NSNumber *componentId;
  @property (nonatomic, strong) NSString *title;

@end

@interface ComponentGroupItem : NSObject

  @property (nonatomic, strong) NSNumber *itemId;
  @property (nonatomic, strong) NSNumber *groupId;
  @property (nonatomic, strong) NSString *title;

@end

person Centurion    schedule 07.05.2013    source источник


Ответы (2)


Вы должны сначала извлечь идентификаторы групп

NSArray *groupIds = [filteredComponentGroupList valueForKey:@"groupId"];

и используйте это для предиката

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"groupId IN %@", groupIds];
NSArray *filteredComponentGroupItemList = [componentGroupItemList filteredArrayUsingPredicate:predicate];
person Martin R    schedule 07.05.2013

На первый взгляд ваша структура данных кажется немного избыточной, но я думаю, вы все продумали.

Если я правильно понимаю ваши требования, у вас уже есть отфильтрованный массив групп компонентов (назовем его filteredComponentGroups) и вы хотите отфильтровать другой массив (componentGroupItemList) с помощью filteredComponentGroups.

В этом случае вы можете использовать оператор IN для NSPredicate и создать массив идентификаторов с valueForKey: в массиве. valueForKey: в массиве создает новый массив только со значениями этого ключа каждого объекта в исходной коллекции. Очень мощный для таких ситуаций.

 NSArray *filteredComponentGroups = // ... your filtered components

 NSArray *componentIdsFromFilteredComponentGroups = [filteredComponentGroups valueForKey: @"groupId"];
 NSPredicate *inFilteredComponentGroupsP = [NSPredicate predicateWithFormat: @"groupId IN %@", componentIdsFromFilteredComponentGroups];

 NSArray *filteredGroupItemList = [componentGroupItemList filteredArrayUsingPredicate: inFilteredComponentGroupsP];

Набирается прямо в браузере, так что остерегайтесь опечаток.

person Monolo    schedule 07.05.2013
comment
Теперь вы были на 8 секунд быстрее :-) - Если я правильно понял, то нужен ключ groupId, а не componentId, но я могу ошибаться. - person Martin R; 07.05.2013