从JSON过滤NSArray?

3
我正在尝试在我的应用程序中实现可搜索的表格视图,当有人搜索位置并获取结果时。它看起来像这样:enter image description here 我从genomes.com获取我的数据源,其中不仅包括城市,还包括公园、建筑、县等等。我只想显示城市位置。
数据是一个JSON文件,由JSONKit解析。整个文件被读入(最多20个对象),然后可搜索的表格视图会显示出来。我不确定是否应该以不同的方式解析JSON文件,或者是否应该使表格视图仅显示所需的结果。(在这种情况下,性能不是问题。)JSON文件被转换为NSArray。
以下是数组的一部分:
 {
    adminCode1 = MA;
    adminCode2 = 027;
    adminName1 = Massachusetts;
    adminName2 = "Worcester County";
    adminName3 = "";
    adminName4 = "";
    adminName5 = "";
    continentCode = NA;
    countryCode = US;
    countryName = "United States";
    elevation = 178;
    fcl = A;
    fclName = "country, state, region,...";
    fcode = ADMD;
    fcodeName = "administrative division";
    geonameId = 4929431;
    lat = "42.2000939";
    lng = "-71.8495163";
    name = "Town of Auburn";
    population = 0;
    score = "53.40083694458008";
    timezone =         {
        dstOffset = "-4";
        gmtOffset = "-5";
        timeZoneId = "America/New_York";
    };
    toponymName = "Town of Auburn";
},

我希望做的是,如果“fcl”(在数组中可见)等于P,则希望在表格视图中显示它。如果“fcl”是其他字符,则不希望在表格视图中看到它。我相信if语句可以做到这一点,但我不知道如何过滤其中的一部分。
任何帮助都将不胜感激!谢谢
编辑:截至目前,以下是搜索代码:
    - (void)delayedSearch:(NSString*)searchString
{
    [self.geoNamesSearch cancel];
    [self.geoNamesSearch search:searchString
                        maxRows:20
                       startRow:0
                       language:nil];
}

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
    self.searchDisplayController.searchBar.prompt = NSLocalizedStringFromTable(@"ILGEONAMES_SEARCHING", @"ILGeoNames", @"");
    [self.searchResults removeAllObjects];

    // Delay the search 1 second to minimize outstanding requests
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
    [self performSelector:@selector(delayedSearch:) withObject:searchString afterDelay:0];

    return YES;
}

如果你没有得到大量的结果,那么最简单的方法可能就是丢弃你不想要的结果。即让JSON解析器完成其任务,循环遍历结果,并将感兴趣的记录复制到一个新的NSMutableArray中。 - Brian
@rhooligan 我很想这样做……但我不太确定该怎么做 :P。能指点一下方向就太好了,谢谢! - sridvijay
你做到哪一步了?你能让解析器返回一个NSArray的NSDictionary对象或类似的吗? - Brian
解决这个问题的关键是要考虑每个UITableView都应该有一个核心索引数据模型(例如,一个NSArray),其中indexpath之间始终存在直接关系 - 这样你的UITableViewDelegate代码就变得简单了。在这种情况下,当搜索文本发生变化时,您需要重新计算此数组。当搜索被取消并且您想要返回显示所有条目时,应保留原始数据源不变。 - ChrisH
4个回答

3
你的问题基本上是如何从搜索栏字符串中过滤你的数组?如果是这样,你可以通过 UISearchBarDelegate 检测文本更改,然后遍历你的数组,复制那些包含你正在寻找的字符串的对象,即:

这是你想要的代理方法:searchBar:textDidChange:

[filterArray removeAllObjects];
for(int i = 0; i < [normalArray count]; i++){
    NSRange textRange;
    textRange =[[[[normalArray objectAtIndex:i] objectForKey:@"name"] lowercaseString] rangeOfString:[searchBarString lowercaseString]];
    //I wasn't sure which objectForKey: string you were looking for, just replace the one you want to filter.
       if(textRange.location != NSNotFound)
       {

        [filterArray addObject:[normalArray objectAtIndex:i]];

       }
}

filterTableView = YES;
[tableView reloadData];

请注意filterTableView的布尔值,这样您的tableView就知道是正常加载还是刚刚制作的筛选版本。您可以在以下位置实现它:
tableView:numberOfRowsInSection:  //For number of rows.
tableView:cellForRowAtIndexPath:  //For the content of the cells.

希望这是您正在寻找的内容。

2
NSMutableArray* filtered = [[NSMutableArray alloc] autorelease];

for (int i=0;i<[data count];i++)
{
   NSDictionary* item=[data objectAtIndex:i];

   if (@"P" == [item objectForKey:@"fcl"] )
  {
    [filtered addObject:item];
  }
}

非常感谢!在对代码进行了几次编辑后,它完美地实现了! - sridvijay

1
每次搜索框的内容改变时,您都需要计算一个新的数组,然后重新加载tableview。行数将是过滤数组中的行数。
要计算新的数组,可以这样做(假设有字典数组):
NSString *searchString; // from the search field
NSMutableArray *array = [NSMutableArray arrayWithCapacity:[origArray count]];
for(NSDictionary *dict in origArray) {
  NSString *val = [dict objectForKey:@"fcl"];
  if([val length] >= searchString) {
    NSString subString = [val substringToIndex:[searchString length]];
    if([subString isEqualToString:val]) [array addObject:dict];
  }
}

每个单元格将从新数组中获取其值。

0

只需将您的JSON放入NSDictionary中,然后简单地执行以下操作:

if ([[yourJson objectForKey:@"fcl"] stringValue] == @"A")
    //doSomething

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接