过滤对象的 NSArray 以具有唯一的 属性 个对象

Filter NSArray of objects to have unique property object

我有 Manager 对象和 Account 对象。经理对象有一个 属性 帐户。

有一个Manager对象的NSArray,需要Account唯一!

示例数组:

    NSArray *managers = @[Manager1(has Account1), Manager2(has Account1), Manager3(has Account1), Manager4(has Acconut2), Manager5(has Account2)];

我需要一个只有 Manager1 和 Manager4 的 NSArray。

假设您有一个单独的数组,唯一地 (!) 包含帐户,并进一步假设您的 类 符合键值,我将枚举该帐户数组并找到管理每个帐户的所有经理。然后选择第一个管理器并将其添加到一个新数组中,如下所示:

NSMutableArray *filteredManagers = [NSMutableArray array];

for (Account *account in accounts) {

   NSArray *managersForAccount = [managers filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"account == %@", account];

   [filteredManagers addObject:[managersForAccount firstObject]];

}

// do something with filteredManagers

您需要在 Manager class 中覆盖 isEqual 方法(也可能在 Account class 中)。之后,通过首先检查将经理添加到数组中,如果数组已经包含具有此类帐户的经理。检查以下可能的解决方案:

  1. 覆盖管理器 isEqual
- (BOOL)isEqual:(id)object {
  if (object == self) {
    return YES;
  } else if (![object isKindOfClass:[Manager class]]) {
    return NO;
  }

  Manager *manager = (Manager *)object;
  return [self.account isEqual:manager.account];
}
  1. 覆盖 Account isEqual(注意! 仅在需要时)
- (BOOL)isEqual:(id)object {
  if (object == self) {
    return YES;
  } else if (![object isKindOfClass:[Account class]]) {
    return NO;
  }

  Account *account = (Account *)object;
  return [self.someUniqueId isEqual:account.someUniqueId];
}
  1. 过滤器数组:
  NSMutableArray *filteredManagers = [NSMutableArray array];
  [managers enumerateObjectsUsingBlock:^(Manager *manager, NSUInteger idx, BOOL *stop) {
    if (![filteredManagers containsObject:manager]) {
      [filteredManagers addObject:manager];
    }
  }];

你需要的是distinctUnionOfObjects

[managers valueForKeyPath:@"@distinctUnionOfObjects.Account"];

这是documentation

@distinctUnionOfObjects The @distinctUnionOfObjects operator returns an array containing the distinct objects in the property specified by the key path to the right of the operator.

以下示例 returns 交易中的收款人 属性 值已删除任何重复值的交易:

NSArray *payees = [transactions valueForKeyPath:@"@distinctUnionOfObjects.payee"];

生成的 payees 数组包含以下字符串:Car Loan、General Cable、Animal Hospital、Green Power、Mortgage。

@unionOfObjects 运算符类似,但不会删除重复对象。

NSArray *managers = // The 5 Manager objects in your example
NSMutableArray *filteredManagers = [NSMutableArray array];
NSMutableArray *accountsManaged = [NSMutableArray array];

for (Manager *manager in managers) {
    if (![accountsManaged containsObject:manager.account]) {
        [filteredManagers addObject:manager];
        [accountsManaged addObject:manager.account];
    }
}

// filteredManagers now contains Manager1 and Manager4