带有数组的 nsdictionary nspredicate 过滤
Posted
技术标签:
【中文标题】带有数组的 nsdictionary nspredicate 过滤【英文标题】:nsdictionary with arrays nspredicate filtering 【发布时间】:2015-01-19 16:40:33 【问题描述】:我有一个表格视图,我想通过可搜索的方式进行搜索。它以前可以工作,但是当我添加部分时,我遇到了麻烦,因为我必须从数组更改为字典。
所以基本上我有一个看起来像这样的 NSDictionary
@"districtA": array with point objects, @"districtB": array with point objects
我需要根据数组中的点 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)'
【问题讨论】:
【参考方案1】:我已经阅读了 cmets,你是对的。我的代码有问题。
我更改了逻辑,我添加了更多步骤(例如创建不需要它的 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,它根据键(区)读取字典对象
【讨论】:
【参考方案2】:您的描述似乎很清楚[self.PointList allValues]
不是Point 对象数组,而是Point 对象数组数组。这就是你的困难的根源,包括你最初的崩溃。
您需要决定如何处理;例如,如果您只想要一个大的 Point 对象数组,则在过滤之前将数组数组展平。我无法进一步建议您,因为对我来说您想要的最终结果并不明显。
编辑您现在已经修改了代码,我可以更清楚地看到您要做什么。您有一个字典,其值是点数组,并且您试图从每个数组中过滤出一些点。我会做的是 that - 即,通过键运行,提取每个数组,过滤它,然后将其放回(如果数组现在为空,则删除键)。但是我可以看到你所做的应该是可行的,因为你巧妙地将键放在开始的点中,所以你可以从中重建字典结构。
【讨论】:
这让我思考并改变了逻辑,它有效并且更容易理解。检查这是否是正确的方法.. 我还添加了我想要的以及我想要的原因 是的,看起来更好。 :) 这不是我会做的——你正在丢失原来的字典键——但我想它是有效的,因为这些点也包含这些键作为它们的district
。我会做的是提取每个键的值数组,过滤它,然后再放回去。以上是关于带有数组的 nsdictionary nspredicate 过滤的主要内容,如果未能解决你的问题,请参考以下文章
如何将带有对象数组的 json 字符串转换为带有 nsdictionaries 的 nsarray - IOS
使用带有数组的 NSDictionary 创建 JSON 文件
带有 NSArray 的 UITableview 包含 NSDictionary 和 NSDictionary 包含另一个 NSDictionary