按数字对 Firebase NSMutableArray 进行排序

Sorting a Firebase NSMutableArray Numerically

我试图通过将战斗力最高的用户放在顶部,将战斗力最低的用户放在底部来对我的 Firebase 数据进行排序。但是,我以前从未使用过 NSSortDescriptor 并且它不起作用。这崩溃并说:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSDictionaryM sortedArrayUsingDescriptors:]: unrecognized selector sent to instance 0x174056e60'

-(void) getObjectCount
{
    self.ref = [[FIRDatabase database] reference];
    posts = [ref child:@"posts"];

    [posts observeEventType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot *snapshot)
     {
         myCount = snapshot.childrenCount;
         for (snapshot in snapshot.children)
         {
            self.userPosts = snapshot.value;

             NSLog(@"BEFORE Sorting *** : %@",userPosts.description);

             NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"Combat Power" ascending:NO];
             NSArray *sorter = @[ sort ];
             NSArray *sortedArray = [userPosts sortedArrayUsingDescriptors:sorter];

             NSLog(@"After Sorting *** : %@",sortedArray.description);
         }
         [self.tableView reloadData];
     }];
}

userPosts 是一个 NSDictionary 类型的对象。你不能对字典中的项目进行排序,这没有多大意义。首先将您的项目放入数组中。

下面是一个读取用户节点并遍历每个用户并将其添加到数组的示例。然后按名称排序数组

users
  -uid_0
    name: "User 0"
  -uid_1
    name: "User 1"
  -uid_2
    name: "User 2"


//assume self.userArray is initialized as an empty array
//  and myRef is the users node shown above
[myRef observeSingleEventOfType:FEventTypeValue withBlock:^(FDataSnapshot *snapshot) {
    for ( FDataSnapshot *child in snapshot.children) {
         NSDictionary *dict = child.value; //move each child into a dictionary
         [self.userArray addObject:dict] //add each dict to the array
    }

    //sort the array by name
    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"name"
                                             ascending:YES]; //sorting by 'name' ascending
    //now build the sortDescriptor array which is required to perform the sort
    NSArray *arrayOfDescriptors = [NSArray arrayWithObject:sortDescriptor];

    //now sort the array in place
    [self.userArray sortUsingDescriptors: arrayOfDescriptors];

}

另一种选择是让 Firebase return 使用 orderedBy 按战斗力排序的数据。

然后在遍历快照时将每个子项插入到数组的索引 0 中。将导致读入的最后一个对象(最高战斗力)位于数组中的位置 0。

    for ( FDataSnapshot *child in snapshot.children) {
         NSDictionary *dict = child.value;
         [self.userArray insertObject:dict atIndex:0]
    }

我认为下面的代码对我有用。

//assume userPosts is initialized as an empty mutable array
-(void) getObjectCount
{
    [[_ref child:@"posts"] observeEventType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot *snapshot)
     {
         myCount = snapshot.childrenCount;
         for (snapshot in snapshot.children)
         {
             self.userPosts = snapshot.value;

             NSLog(@"BEFORE Sorting *** : %@",userPosts.description);
             NSSortDescriptor *sortDescript = [NSSortDescriptor sortDescriptorWithKey:@"Combat Power" ascending:YES];
             [userPosts sortUsingDescriptors:[NSArray arrayWithObject:sortDescript]];

             NSLog(@"After Sorting *** : %@",userPosts.description);
         }
         [self.tableView reloadData];
     }];
}

并插入 "Combat Power" 的键,这样您就可以添加字符串格式的值。例如 firebase 数据库显示在这种格式之下。

{
     Combat Power : "1854" 
}

通过查看崩溃前打印的日志,snapshot.value 显然是 NSDictionary 对象。请按以下方式修改您的代码,它应该可以工作。

-(void) getObjectCount
{
    self.ref = [[FIRDatabase database] reference];
    posts = [ref child:@"posts"];

    [posts observeEventType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot *snapshot)
    {
         UInt32 myCount = snapshot.childrenCount;
         for (snapshot in snapshot.children)
         {
             id value = snapshot.value;
             if ([value isKindOfClass:[NSDictionary class]] {
                 value = @[value]
             }
             self.userPosts = value;

             NSLog(@"BEFORE Sorting *** : %@",userPosts.description);

             NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"Combat Power" ascending:NO];
             NSArray *sorter = @[ sort ];
             NSArray *sortedArray = [userPosts sortedArrayUsingDescriptors:sorter];

             NSLog(@"After Sorting *** : %@",sortedArray.description);
         }
         [self.tableView reloadData];
     }];
}

我让它工作的方法是在 get 方法中使用“queryOrderedByChild”,然后 yourNewArray = [yourArray reverseObjectEnumerator].allObjects 阵列的。

最简单的方法。