如何删除具有相同属性值但在 NSMutableArray 中有一个的所有对象
Posted
技术标签:
【中文标题】如何删除具有相同属性值但在 NSMutableArray 中有一个的所有对象【英文标题】:How to remove all objects with the same property value but one in NSMutableArray 【发布时间】:2013-09-15 20:24:32 【问题描述】:我有一个带有 url 字符串属性和标题的历史对象。我想使用包含搜索字符串的 url 搜索所有对象的历史记录,然后删除所有重复项。
示例: 我有一组历史对象,其中 20 个都是“https://www.google.com”,4 个是“https://www.google.com/#q=search”,我想返回一个数组,其中只有一个 url 值为“https://www.google.com”的对象和一个“https://www.google.com/#q=search”的url值
这是我当前的代码,它搜索历史并返回与字符串匹配的所有对象:
- (NSArray *)historyObjectsContainingQuery:(NSString *)query
NSMutableArray *matchingObjects = [[NSMutableArray alloc] init];
HistoryManager *HM = [HistoryManager sharedInstance];
for (int i=0; i<[[HM history] count]; i++)
//History "days"
HistoryObject *historyItem = HistoryObject([[HistoryManager sharedInstance] history][i]);
for (int o=0; o<[historyItem.objects count]; o++)
//Each object inn each history day
HistoryObject *HO = HistoryObject(historyItem.objects[o]);
if ([HO.title rangeOfString:query options:NSCaseInsensitiveSearch].location != NSNotFound)
//history objects with their title containing the query string
[matchingObjects addObject:HO];
return matchingObjects;
然后我记录每个 url 值:
self.foundInBookmarksAndHistory = [self historyObjectsContainingQuery:textField.text]; for (HistoryObject *HO in self.foundInBookmarksAndHistory) NSLog(@"%@",HO.url);
结果如下:
https://www.google.com/
2013-09-15 13:48:49.382 Flow HD[3599:60b] https://www.google.com/
2013-09-15 13:48:49.384 Flow HD[3599:60b] https://www.google.com/
2013-09-15 13:48:49.385 Flow HD[3599:60b] https://www.google.com/
2013-09-15 13:48:49.387 Flow HD[3599:60b] https://www.google.com/
2013-09-15 13:48:49.388 Flow HD[3599:60b] https://www.google.com/
2013-09-15 13:48:49.390 Flow HD[3599:60b] https://www.google.com/
2013-09-15 13:48:49.391 Flow HD[3599:60b] https://www.google.com/search?q=yahoo
2013-09-15 13:48:49.392 Flow HD[3599:60b] https://www.google.com/
2013-09-15 13:48:49.394 Flow HD[3599:60b] https://www.google.com/
2013-09-15 13:48:49.395 Flow HD[3599:60b] https://www.google.com/search?q=Sup
2013-09-15 13:48:49.397 Flow HD[3599:60b] https://www.google.com/
2013-09-15 13:48:49.398 Flow HD[3599:60b] https://www.google.com/
2013-09-15 13:48:49.400 Flow HD[3599:60b] https://www.google.com/
2013-09-15 13:48:49.402 Flow HD[3599:60b] https://www.google.com/
2013-09-15 13:48:49.404 Flow HD[3599:60b] https://www.google.com/
2013-09-15 13:48:49.405 Flow HD[3599:60b] https://www.google.com/
还有很多,我如何删除具有相同值的每个对象?对象不相等,但确实具有相等的 url。
我尝试过 NSPredicate 并使用更多的 for 循环来遍历并找到匹配的对象,但我总是留下 2 个或更多具有相同属性的相同对象。
【问题讨论】:
【参考方案1】:你可以这样做:
NSMutableSet *seenObjects = [NSMutableSet set];
NSPredicate *dupPred = [NSPredicate predicateWithBlock: ^BOOL(id obj, NSDictionary *bind)
HistoryObject *hObj = (HistoryObject*)obj;
BOOL seen = [seenObjects containsObject:hObj.title];
if (!seen)
[seenObjects addObject:hObj.title];
return !seen;
];
NSArray *yourHistoryArray = ... // This is your array which needs to be filtered
NSArray *yourHistoryArray = [yourHistoryArray filteredArrayUsingPredicate:dupObjectsPred];
【讨论】:
dupPred = dupObjectsPred【参考方案2】:我不确定这是搜索所有对象的最佳方式,但除了我能为您的代码想到的最简单的解决方法是替换
if ([HO.title rangeOfString:query options:NSCaseInsensitiveSearch].location != NSNotFound)
[matchingObjects addObject:HO];
用这个:
if ([HO.title rangeOfString:query options:NSCaseInsensitiveSearch].location != NSNotFound)
HistoryObject *temp = HistoryObject(historyItem.objects[o]);
[historyItem.objects removeObjectAtIndex:o];
//And after all the `for` loops
[historyItem.objects addObject:temp];
您删除了所有匹配的对象并将其添加到数组中。
编辑:
阅读您的编辑后,使用isEqualToString
而不是rangeOfString
。 rangeOfString
会在 abcd、abce 和 abcf 中找到单词 abc,这不是你想要的。 isEqualToString
for abc 仅对 abc 有效,其他无效。
【讨论】:
啊,具有 objects 属性的 History 对象是历史天数,我只是想通过每天匹配一个字符串来获取每个历史记录对象之一。所以在我上面的代码中,它每天都经过,然后获取每个对象的 url 属性值与查询匹配。但我得到多个对象(不同),但 url 值是相同的 那么为什么不使用isEqualToString
而不是 rangeOfString
呢? rangeOfString
将在 abcd、abce 和 abcf 中找到单词 abc。 isEqualToString
for abc 仅对 abc 有效,其他无效。
这是一个网络浏览器应用程序。所以这是搜索历史。如果我有一个 url 为“google.com”和类似“search.yahoo.com/…”的历史对象,它不匹配,但它有谷歌,所以我也想要。但我得到的比我需要的多。我用每个值的日志更新了我的帖子。
我的第一个答案仍然有效,使用 isEqualToString
,如果它是 TRUE 删除对象。对所有历史都这样做。完成后将相同的对象读取到您的数组中。【参考方案3】:
如果对象仍然存在,则循环可变数组(必要时将数组更改为可变数组)
while ([farray containsObject:_data])
[farray removeObject:_data];
【讨论】:
以上是关于如何删除具有相同属性值但在 NSMutableArray 中有一个的所有对象的主要内容,如果未能解决你的问题,请参考以下文章
具有相同值但不同类型的参数的 std::floor 函数的不同值
带有 ggplots 的 for 循环生成具有相同值但标题不同的图形