Objective-C - 使用自定义子对象删除重复项

时间:2015-01-27 10:58:11

标签: objective-c nsarray filtering nspredicate

我有一个列出出站和入境机场代码的弹出式列表,如下所示:

Leg -- JFK DXB
Leg -- JFK DXB
Leg -- LS14 CFR
Leg -- LS14 EGSG
Leg -- OXF CFR
Leg -- OXF CFR
Leg -- JFK DXB
Leg -- DXB OXF
Leg -- DXB JFK
Leg -- CFR GVA
Leg -- JFK TDX
Leg -- JFK DXB
Leg -- TDX DXB
Leg -- GVA OXF

我想删除出发和到达匹配的所有重复项(即:JFK - DXB)

机场代码是自定义子代码或第三方对象,因此它不像进行字符串比较那么简单。

在下面我循环以摆脱任何零对象

    NSArray *charters = [CharterRequest charterRequestsForUser:[User currentUser] inContext:[NSManagedObjectContext mainContext]];

NSMutableArray *charterReq = [NSMutableArray array];

    for (CharterRequest *request in charters)
    {
        CharterRequestLeg *leg = [request initialLeg];
        if ( (leg.departureAirport.code != nil) && (leg.destinationAirport.code != nil) ) {
            [charterReq addObject:request];
        }
    }

最终我将在终端输出机场代码

// someIndex could be any index, but lets say its 1 for now
    VICCharterRequest *request = charterReq[someIndex];
    VICCharterRequestLeg *leg = [request initialLeg];

    NSString *returnedString =  [NSString stringWithFormat:@"%@ - %@", leg.departureAirport.code, leg.destinationAirport.code];
    NSLog(@"Leg = %@", returnedString);

我遇到的问题是我有很多重复的目的地/到达机场,如JFK DXB会多次出现。

有没有合理的方法来摆脱所有重复,留下独特的?

非常感谢


目前我有这个代码,它总是返回50.由于重复,它应该比这少得多;

// Filter out nils
        for (VICCharterRequest *request in charters)
        {
            VICCharterRequestLeg *leg = [request initialLeg];
            if ( (leg.departureAirport.code != nil) && (leg.destinationAirport.code != nil) ) {
                [list addObject:request];
            }
        }

        NSMutableSet *seenItems = [NSMutableSet set];

        NSPredicate *dupPred = [NSPredicate predicateWithBlock: ^BOOL(id obj, NSDictionary *bind) {

            VICCharterRequestLeg *leg = [obj initialLeg];

            BOOL seen = ([seenItems containsObject:leg.departureAirport] && [seenItems containsObject:leg.destinationAirport]);
            //[seenItems containsObject:leg];

            if (!seen) {
                [seenItems addObject:obj];
            }
            return !seen;
        }];


        NSArray *filtered = [list filteredArrayUsingPredicate:dupPred];
        NSLog(@"Filtered = %lu", filtered.count);

2 个答案:

答案 0 :(得分:1)

您需要设置一些类似的方法。

例如:

- (BOOL)isEqualToVICCharterRequest:(VICCharterRequest *)request {
  if (!request) {
    return NO;
  }

  BOOL depEqual = (!self.departureAirport.code && !request.departureAirport.code) || [self.departureAirport.code isEqualToString:request.departureAirport.code];

  BOOL arrEqual = (!self.destinationAirport.code && !request.destinationAirport.code) || [self.birthday isEqualToDate:request.destinationAirport.code];

  return depEqual && arrEqual;
}

然后您的循环代码将是:

for (CharterRequest *request in charters)
{
    CharterRequestLeg *leg = [request initialLeg];
    if ( ![request isEqualToVICCharterRequest:leg] ) {
        [charterReq addObject:request];
    }
}

如果你想要更深入:

#pragma mark - NSObject

- (BOOL)isEqual:(id)object {
  if (self == object) {
    return YES;
  }

  if (![object isKindOfClass:[VICCharterRequest class]]) {
    return NO;
  }

  return [self isEqualToVICCharterRequest:(isEqualToVICCharterRequest *)object];
}

- (NSUInteger)hash {
  return [self.departureAirport.code hash] ^ [self.destinationAirport.code hash];
}

答案 1 :(得分:0)

NSArray* array = ... // you can add your data to this array
NSMutableSet* existingset  = [NSMutableSet set];
NSMutableArray* finalArray = [NSMutableArray array];
for (id object in array) {
   if (![existingset containsObject:[object name]]) {
      [existingset addObject:[object name]];
      [finalArray addObject:object];
   }
}