【问题标题】:Sorting NSDictionary based UITableView by key按键排序基于 NSDictionary 的 UITableView
【发布时间】:2012-04-24 18:42:07
【问题描述】:

我有一个自定义 UITableView,它由带入 NSMutableDictionary 的 JSON 数据填充。然后我创建一个 mutablecopy,以便可以将 distanceFromLocation 方法的值添加到字典中。我要做的是然后使用该新对象按最近距离对单元格进行排序。我看过其他使用 NSSortDescriptor 的例子,但那是在谈论排序数组。如何对字典中的单元格进行排序或从字典中创建一个数组以使用 NSSortDescriptor?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{

static NSString *CellIdentifier = @"dealerlistcell";

DealerListCell *cell = (DealerListCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) 
{
    cell = [[DealerListCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}

//gets JSON data and loads into Dictionary
NSMutableDictionary *info = [json objectAtIndex:indexPath.row];
NSMutableDictionary *infocopy = [info mutableCopy];

//pulls the current user location
CLLocation *currentlocation2 = [[CLLocation alloc] initWithLatitude:locationManager.location.coordinate.latitude longitude:locationManager.location.coordinate.longitude];

//gets the latitude and longitude from info dictionary to calculate distancefromlocation for each cell
CLLocation *locationforindex = [[CLLocation alloc] initWithLatitude:[[info objectForKey:@"dlrlat"]doubleValue] longitude:[[info objectForKey:@"dlrlong"]doubleValue]];

//calculates the distance
CLLocationDistance dist = ([locationforindex distanceFromLocation:currentlocation2]*0.0006213711922);

//format the distance to a string for the label
NSString *distancestring = [NSString stringWithFormat:@"%.1f miles",dist];

//create object with distance to add to dictionary
NSNumber *distance = [NSNumber numberWithDouble:dist];

编辑:分配到对象的距离,以便稍后在 NSSortDescriptor 中调用

//add to dictionary 
[infocopy setObject:distance forKey:@"distance"];

//create array from dictionary
NSDictionary *aDict = [NSDictionary dictionaryWithDictionary:infocopy];
NSArray *anArray = [aDict allValues];

//implemented NSSortDescriptor
NSSortDescriptor *sorter [[NSSortDescriptor alloc] initWithKey:@"distance" ascending: YES];
NSArray *sortdescriptors = [NSArray arrayWithObject:sorter];
[anArray sortedArrayUsingDescriptors:sortdescriptors];

但是,它会为键距离抛出 valueForUndefinedKey。如何在“initWithKey”中定义距离键?

【问题讨论】:

    标签: ios xcode uitableview sorting nsdictionary


    【解决方案1】:

    通过这个论坛和我朋友的一些帮助,我能够拼凑出这个解决方案。

    答案是在加载表格视图之前使用 for 循环并为方法中的每个位置创建字典。然后我使用 NSSortDescriptor 进行排序,效果很好。

    最终解决方案见下面的代码。

    -(void)getData:(NSData *) data 
    {
    
    NSError *error;
    
    // load the jsonArray with the JSON Data
    jsonArray = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
    
    
    //define the unsorted dealers array
    unsortedDealers = [[NSMutableArray alloc] initWithCapacity:1000];
    
    // start at row 0
    int index = 0;
    
    // loop through each dealer and calculate distance from current location
    for (NSDictionary *dealer in jsonArray) 
    {
        //create dictionary from JSON Array
        infoDict = [jsonArray objectAtIndex:index];
    
        //get the coordidates from current location
        CLLocation *currentlocation = [[CLLocation alloc] initWithLatitude:locationManager.location.coordinate.latitude longitude:locationManager.location.coordinate.longitude];
    
        //get the coordinates for dealer at row
        // dlr lat and longs are switched in the database
        CLLocation *locationforindex = [[CLLocation alloc] initWithLatitude:[[infoDict objectForKey:@"dlrlong"]doubleValue] longitude:[[infoDict objectForKey:@"dlrlat"]doubleValue]];
    
        //calculate the distance from current location to dealer at row and format it in miles
        CLLocationDistance dist = ([locationforindex distanceFromLocation:currentlocation]*0.0006213711922);
    
        //define the distance for display
        NSNumber *distanceForDict = [NSNumber numberWithDouble:dist];
    
        //define the distance for sorting
        NSString *distanceForSort = [NSString stringWithFormat:@"%.1f",dist];
    
       //create a dictionary for each dealer and define the values for each key 
       NSMutableDictionary *dealerDict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[infoDict objectForKey:@"dlrname"] , @"dlrname", [infoDict objectForKey:@"dlrcity"], @"dlrcity", [infoDict objectForKey:@"dlrstate"] , @"dlrstate", [infoDict objectForKey:@"dlrzip"], @"dlrzip", [infoDict objectForKey:@"dlradd"] , @"dlradd", distanceForDict , @"dlrdistance" , distanceForSort , @"dlrsortdistance" , [infoDict objectForKey:@"dlremail"] , @"dlremail" , [infoDict objectForKey:@"dlrfax"] , @"dlrfax" , [infoDict objectForKey:@"dlrhours"] , @"dlrhours" , [infoDict objectForKey:@"dlrlat"], @"dlrlat",[infoDict objectForKey:@"dlrlong"] , @"dlrlong" , [infoDict objectForKey:@"dlrnum"], @"dlrnum",[infoDict objectForKey:@"dlrphone"] , @"dlrphone" , [infoDict objectForKey:@"dlrwebsite"], @"dlrwebsite", nil];
    
        //add dictionary to the unsorted array
        [unsortedDealers addObject:dealerDict];
    
        // iterate through the list of dealers
        ++index;
    
    }
    
    // creates the sorting element
    NSSortDescriptor *sortDescriptor;
    
    //define what you want to sort by
    sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"dlrdistance" ascending:YES];
    
    // build new array with thosed elements to be sorted
    NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
    
    // create new array based on the sorted value
    sortedDealers = [unsortedDealers sortedArrayUsingDescriptors:sortDescriptors];  
    
    [self.tableView reloadData];
    
    //error message if there is no data found. Usually this is an error with the connection, 
    //it should never return empty
    if (jsonArray ==  nil) 
    {
        NSLog(@"No Data Loaded. Please check your internet connection");
    }
    

    }

    【讨论】:

      【解决方案2】:

      如果你这样做:

      NSDictionary *aDict = [NSDictionary dictionaryWithDictionary:info];
      NSArray *anArray = [aDict allValues];
      

      它将返回一个数组,然后您可以使用 NSSortDescriptor 对其进行排序。

      【讨论】:

      • 当我尝试在 NSSortDescriptor 中使用“距离”时,它会抛出一个 valueForUndefinedKey
      • 抱歉,您的数组包含哪些类型的对象?如果我没记错的话,它应该是一个字典数组,以便排序描述符在数组中的每个对象上都有要比较的键。我对此有点陌生,但我认为这就是正在发生的事情。
      • 它从一个 JSON 序列化到一个名为 info 的 NSDictionary 开始。它具有位置名称、地址等值,以及 dlrnamedlrcity 等键值。我已经弄清楚如何插入 distanceFromLocation 转换为具有相应键的值。使用 NSLog,我已经验证了距离(NSNumber)存储在键 distance 中。我遇到的问题是如何使用 NSSortDescriptor 根据距离对 UITableView 进行排序
      • 我想我明白你在说什么。但是你的数组中只有一个 NSDictionary 吗?或者有几个,每个代表一个位置?如果是后者,并且您已经确认要排序的值与距离键相关联,那么它应该只是 NSSortDescriptor *sd = [[NSSortDescriptor alloc] initWithKey:@"distance " 升序:是]; NSArray *sortedArray = [数组 sortedArrayUsingDescriptors:[NSArray arrayWithObject:sd]]; “array”是包含您的字典的那个。记录并排序结果。
      • 那么您将使用 sortedArray 作为填充表格的数据。
      猜你喜欢
      • 1970-01-01
      • 2011-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多