如果我们阅读“过滤重复”,我们自然会想到集合和过滤操作。但是在这种情况下这会很麻烦,因为重复项并不是真正的重复项,并且 NSSet 不会给我们机会来决定更喜欢哪个项目。
我选择先根据其 typeID 对项目进行分段,然后在每个分段中选择第一个对象,然后根据其 id 对它们进行排序。
准备工作
我使用这个Item 类:
@interface Item : NSObject
@property NSInteger itemID;
@property NSInteger typeID;
@property(copy) NSString *itemDescription;
@end
@implementation Item
-(NSString *)description
{
return [NSString stringWithFormat:@"Item: %li, typeID: %li, description: %@", (long)self.itemID, (long)self.typeID, self.itemDescription];
}
@end
请注意,id 和 description 是相当糟糕的属性名称。
我使用此代码创建项目列表:
NSArray *data =@[ @{@"itemID": @1, @"typeID": @7, @"description": @"some text 1"},
@{@"itemID": @2, @"typeID": @7, @"description": @"some text 2"},
@{@"itemID": @3, @"typeID": @5, @"description": @"some text 3"},
@{@"itemID": @4, @"typeID": @5, @"description": @"some text 4"},
@{@"itemID": @5, @"typeID": @8, @"description": @"some text 5"}];
NSMutableArray *items = [@[ ] mutableCopy];
[data enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL *stop) {
[items addObject:({
Item *item = [[Item alloc] init];
item.itemID = [obj[@"itemID"] integerValue];
item.typeID = [obj[@"typeID"] integerValue];
item.itemDescription = obj[@"description"];
item;
})];
}];
这应该是您以类似方式拥有的所有代码。或者你不需要它。
答案
我创建了一个以 typeID 作为键的字典。作为值,我添加并填充可变数组:
NSMutableDictionary *itemsByType = [@{} mutableCopy];
[items enumerateObjectsUsingBlock:^(Item *item, NSUInteger idx, BOOL *stop) {
id key = @(item.typeID);
if (![[itemsByType allKeys] containsObject:key]) {
itemsByType[key] = [@[] mutableCopy];
}
[itemsByType[key] addObject:item];
}];
现在我对每个可变数组进行排序:
[itemsByType enumerateKeysAndObjectsUsingBlock:^(id key, NSMutableArray *items, BOOL *stop) {
[items sortUsingComparator:^NSComparisonResult(Item *item1, Item *item2) {
return item1.itemID < item2.itemID;
}];
}];
并将每个数组的每个第一个对象放入结果中:
NSMutableArray *resultArray = [@[] mutableCopy];
[[itemsByType allKeys] enumerateObjectsUsingBlock:^(id key, NSUInteger idx, BOOL *stop) {
[resultArray addObject:itemsByType[key][0]];
}];
现在我按 itemID 对结果进行排序
[resultArray sortUsingComparator:^NSComparisonResult(Item *item1, Item *item2){
return item1.itemID > item2.itemID;
}];
结果:
NSLog(@"%@", resultArray);
打印
(
"Item: 2, typeID: 7, description: some text 2",
"Item: 4, typeID: 5, description: some text 4",
"Item: 5, typeID: 8, description: some text 5"
)
我的测试程序源码:gist
另一种方法是对 typeID 升序和 itemID 降序进行排序。然后循环这些项目并将每个第一个项目作为一个看不见的类型 id。对 typeID 的结果进行排序。
[items sortUsingDescriptors:@[[[NSSortDescriptor alloc] initWithKey:@"typeID" ascending:YES],
[[NSSortDescriptor alloc] initWithKey:@"itemID" ascending:NO]
]];
NSInteger lastestTypeID = -1;
NSMutableArray *result = [@[] mutableCopy];
for (Item *item in items) {
if (item.typeID > lastestTypeID) {
lastestTypeID = item.typeID;
[result addObject:item];
}
}
[result sortUsingComparator:^NSComparisonResult(Item *obj1, Item *obj2) {
return obj1.itemID > obj2.itemID;
}];