3

我有一个带有 url 字符串属性和标题的历史对象。我想使用包含搜索字符串的 url 搜索对象的所有历史记录,然后删除所有重复项。

示例:我有一组历史对象,其中 20 个都是“ https://www.google.com ”,4 个是“ https://www.google.com/#q=search ”,我想得到返回一个数组,其中只有一个对象,其 url 值为“ https://www.google.com ”,一个 url 值为“ https://www.google.com/#q=search

这是我当前的代码,它搜索历史并返回与字符串匹配的所有对象:

    - (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 个或更多具有相同属性的相同对象。

4

3 回答 3

9

你可以做这样的事情:

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];
于 2013-09-15T21:05:03.080 回答
0

我不确定这是搜索所有对象的最佳方法,但除了我能想到的代码最简单的修复方法是替换

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,这不是你想要的。isEqualToStringfor abc 仅对 abc 有效,其他无效。

于 2013-09-15T20:40:51.053 回答
0

如果对象仍然存在,则循环可变数组(如有必要,将数组更改为可变数组)

while ([farray containsObject:_data]){
       [farray removeObject:_data];
}
于 2017-02-25T04:12:58.653 回答