按数字对 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
阵列的。
最简单的方法。
我试图通过将战斗力最高的用户放在顶部,将战斗力最低的用户放在底部来对我的 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 阵列的。
最简单的方法。