ewizard ewizard - 3 months ago 10
iOS Question

adjust order of one array based on the order of another array that was sorted

I have two tables, one table for usernames, and one table for scores. I populate those tables with two arrays. The tables need to be in descending order based on the scores. I sort the array with the scores in it, but I am not sure how I can arrange the usernames to stick with their score, they are in a separate array, and a separate table from the scores table. Here is my code:

dictionary = [NSDictionary dictionaryWithObjects:matchesForUser forKeys:tableData];
sortedFirstArray = [dictionary allKeys];
sortedSecondArray = [dictionary objectsForKeys:sortedFirstArray notFoundMarker:[NSNull null]];
sortedSecondArray = [sortedSecondArray sortedArrayUsingSelector: @selector(compare:)];


I need the
sortedFirstArray
values to stick with their respective
sortedSecondArray
values in terms of their order in each of their arrays.

UPDATE

My code attempting to do the sorting:

PFQuery *query = [PFQuery queryWithClassName:@"_User"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (!error) {
entries = [NSMutableArray new];
for (PFObject *object in objects) {
NSLog(@"%@", object.objectId);
[tableData addObject:[object valueForKey:@"username"]];
[matchesForUser addObject:[object valueForKey:@"matches"]];

NSMutableDictionary* entry = [NSMutableDictionary new];

entry[@"username"] = [object valueForKey:@"username"];
entry[@"matches"] = [object valueForKey:@"matches"];

[entries addObject:entry];

//transfer = entries;
}
transfer = [entries sortedArrayUsingComparator:^NSComparisonResult(NSDictionary* a, NSDictionary* b) {
NSDate *first = [a objectForKey:@"matches"];
NSDate *second = [b objectForKey:@"matches"];
NSLog(first);
NSLog(second);
return [first compare:second];
}];
//dictionary = [NSDictionary dictionaryWithObjects:matchesForUser forKeys:tableData];
//sortedFirstArray = [dictionary allKeys];
//sortedSecondArray = [dictionary objectsForKeys:sortedFirstArray notFoundMarker:[NSNull null]];
//sortedSecondArray = [sortedSecondArray sortedArrayUsingSelector: @selector(compare:)];
[_tableView reloadData];
[_tableViewScore reloadData];

}else{
NSLog([error description]);
}

NSLog(@"***tabledata***");
NSLog([NSString stringWithFormat:@"%lu", (unsigned long)[tableData count]]);
NSLog(@"***matchesdata***");
NSLog([NSString stringWithFormat:@"%lu", (unsigned long)[matchesForUser count]]);
});
}];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if(tableView.tag == 1) {
static NSString *simpleTableIdentifier = @"SimpleTableItem";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
cell.textLabel.font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:16.0];
cell.textLabel.textColor = [UIColor colorWithRed:218.0f/255.0f green:247.0f/255.0f blue:220.0f/255.0f alpha:1.0f];
cell.backgroundColor = [UIColor colorWithRed:153.0f/255.0f green:211.0f/255.0f blue:212.0f/255.0f alpha:1.0f];
cell.layoutMargins = UIEdgeInsetsZero;
cell.preservesSuperviewLayoutMargins = NO;

if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}

UILabel *contentV = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 230, 44)];
contentV.font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:16.0];
contentV.textColor = [UIColor colorWithRed:218.0f/255.0f green:247.0f/255.0f blue:220.0f/255.0f alpha:1.0f];
contentV.backgroundColor = [UIColor colorWithRed:153.0f/255.0f green:211.0f/255.0f blue:212.0f/255.0f alpha:1.0f];

cell.contentView.layoutMargins = UIEdgeInsetsZero;

NSString *username2 = [[transfer objectAtIndex:indexPath.row] valueForKey:@"username"];

NSLog(@"***username***");
NSLog(username2);

contentV.text = username2;
[cell.contentView addSubview:contentV];

return cell;
}
else {
static NSString *simpleTableIdentifier = @"SimpleTableItem";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
cell.textLabel.font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:16.0];
cell.textLabel.textColor = [UIColor colorWithRed:153.0f/255.0f green:211.0f/255.0f blue:212.0f/255.0f alpha:1.0f];
cell.backgroundColor = [UIColor colorWithRed:218.0f/255.0f green:247.0f/255.0f blue:220.0f/255.0f alpha:1.0f];
cell.textLabel.textAlignment = NSTextAlignmentCenter;

if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}

NSString *matchAmount = [[transfer objectAtIndex:indexPath.row] valueForKey:@"matches"];
NSLog(@"***matchamount***");
NSLog(matchAmount);

cell.textLabel.text = matchAmount;

return cell;

}
}

Answer

Instead of having two separate arrays and going trough the trouble of sorting one of them directly and try to figure out which entries of the other correspond to which in the sorted one, you should instead keep the paired entries of both arrays together in one entity (dictionary or instance of a custom class), and group those in your (single) array:

The actual property names etc. will vary for your code, but the general idea is like this:

self.entries = [NSMutableArray new];

for (int i=0; i < userNameArray.count; i++){

    NSMutableDictionary* entry = [NSMutableDictionary new];

    entry["userName"] = [userNameArray objectAtIndex: i];
    entry["score"   ] = [scoreArray objectAtIndex: i]; 
    // ^ TODO: Make sure scoreArray has at least as many elements 
    // as userNameArray!

    [self.entries addObject: entry];
}

self.entries = [self.entries sortedArrayUsingComparator:^NSComparisonResult(NSDictionary* a, NSDictionary* b) {
    NSDate *first  = [a objectForKey:"score"];
    NSDate *second = [b objectForKey:"score"];
    return [first compare:second];
}];

// (...)

UITableViewCell* tableView:(UITableView*) tableView cellForRowAtIndexPath:(NSIndexPath}) indexPath
{
    NSDictionary* entry = [self.entries objectAtIndex: indexPath.row];

    if (tableView == self.userNameTableView) {
         // (dequeue user cell...)

         cell.titleLabel.text = [entry objectForKey: "userName"];
         return cell
     }
     else{
         // (dequeue score cell...)

         cell.titleLabel.text = [entry objectForKey: "score"];
         return cell
     }
}