nsdictionary与数组nspredicate过滤

时间:2015-01-19 16:40:33

标签: ios objective-c xcode nsdictionary nspredicate

我有一个tableview,我想通过搜索来搜索。它之前有用,但是当我添加了部分时,我遇到了麻烦,因为我不得不从数组更改为字典。

所以基本上我有一个看起来像这样的NSDictionary

{ @"districtA": array with point objects, @"districtB": array with point objects}

我需要根据数组中的point objects.name过滤它们。之后我想创建一个带有过滤对象的新nsdictionary。

我尝试了至少10种不同的方法,但我无法弄明白,所以我认为这是我最积极的唯一方法。 这是我能想到的唯一方法,如果有更简单的方法或更多的逻辑方式,请告诉我。

-(void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope {

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.name BEGINSWITH[c] %@",searchText];

//create new array to fill
NSArray *arrayWithFilteredPoints = [[NSArray alloc] init];

//loop through the values and put into an rray based on the predicate
arrayWithFilteredPoints = [NSArray arrayWithObject:[[self.PointList allValues] filteredArrayUsingPredicate:predicate]];

NSMutableDictionary *dict = [@{} mutableCopy];

for (Point *point in arrayWithFilteredPoints) {
    if (![dict objectForKey:Point.district])
        dict[Point.district] = [@[] mutableCopy];
        [dict[Point.district]addObject:Point];
}

self.filteredPointList = dict;
self.filteredDistrictSectionNames = [[dict allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];}

这会导致崩溃,当然会发生使用谓词的地方,但我不知道如何调试我应该使用的谓词:

on 'NSInvalidArgumentException', reason: 'Can't do a substring operation with something that isn't a string (lhs = (
West ) rhs = w)'

2 个答案:

答案 0 :(得分:0)

我已阅读评论,你说得对。我的代码出了问题。

我更改了逻辑,我添加了一些步骤(比如创建NSArray而不需要它)以使解决方案清晰

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.name BEGINSWITH[c] %@",searchText];

//1. create new array to fill only the Points from the dictionary
NSArray *allPoints = [self.PointList allValues];
NSMutableArray *allPointObjects = [[NSMutableArray alloc]init];

for (NSArray *array in allPoints) {
    for (Point *point in array) {
        [allPointObjects addObject:point];
    }
}

//2. loop through allPointObjects and put into an mutablearray based on the predicate
NSArray *arrayWithFilteredPoints = [[NSArray alloc] init];
arrayWithFilteredPoints = [allPointObjects filteredArrayUsingPredicate:predicate];

NSMutableDictionary *dict = [@{} mutableCopy];

for (Point *point in arrayWithFilteredPoints) {
    if (![dict objectForKey:point.district])
        dict[point.district] = [@[] mutableCopy];
        [dict[point.district]addObject:Point];
}

self.filteredPointList = dict;
self.filteredDistrictSectionNames = [[dict allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

我想要一个过滤后的nsdictionary,我可以传回我的tableview,根据键(区)读取字典对象

答案 1 :(得分:0)

从您的描述中可以清楚地看出,[self.PointList allValues]不是Point对象的数组,而是 Point对象数组的数组。这是你的困难的根源,包括你原来的崩溃。

你需要决定该怎么做;例如,如果只需要一个大的Point对象数组,则在过滤之前展平数组数组。我不能进一步告诉你,因为我不明白你想要的最终结果。

编辑您现在已经修改了代码,我可以更清楚地看到您要执行的操作。你有一个字典,其值是点数组,你试图过滤每个数组中的一些点。我要做的是做那个 - 即,通过密钥运行,提取每个数组,过滤它,然后把它放回去(如果数组现在是空的,则删除密钥)。但是我可以看到你正在做的事情应该有效,因为你已经巧妙地将键放入要开始的点中,所以你可以从中重建字典结构。