Objective-C - 删除带有自定义子对象的重复项

Objective-C - Removing duplicates with custom sub-objects

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

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)

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

在下文中,我正在循环以摆脱任何 nil 对象

    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);

我遇到的问题是我得到了很多重复的 destination/arrival 机场,例如 JFK DXB 会出现多次。

是否有合理的方法来去除所有重复项,留下唯一性?

非常感谢


目前我有这个代码,它总是 returns 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);
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];
   }
}

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

例如:

- (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];
}