使用值对 NSDictionary 的 NSArray 进行排序

Posted

技术标签:

【中文标题】使用值对 NSDictionary 的 NSArray 进行排序【英文标题】:Sort NSArray of NSDictionary using value [duplicate] 【发布时间】:2014-02-15 05:15:57 【问题描述】:

我有一个 NSArrayNSDictionaries。在NSDictionary 中,我有一个名为“rowID”的元素,它保存为NSString。但是,其中保存的所有内容都是数字,即使它们保存为字符串。

我想知道如何根据这个值对数组进行排序,但在排序 1-100 方面。目前,当我对它进行排序时,它应该是 1-10,10 排在第一位。

这就是我的排序方式:

NSArray *tempSortedItemsArray = [itemArray sortedArrayUsingDescriptors:
                                     @[[NSSortDescriptor
                                        sortDescriptorWithKey:@"rowID" ascending:YES]]];

【问题讨论】:

【参考方案1】:

试试这个:-

NSArray *aSortedArray = [itemArray sortedArrayUsingComparator:^(NSMutableDictionary *obj1,NSMutableDictionary *obj2) 
    NSString *num1 =[obj1 objectForKey:@"rowID"];
    NSString *num2 =[obj2 objectForKey:@"rowID"];
    return (NSComparisonResult) [num1 compare:num2 options:(NSNumericSearch)];
];

【讨论】:

这是不正确的。 OP 已声明 rowID 是 NSString 对象,而不是 NSNumber 对象。这最终会进行同样的错误字符串比较。 它在我的最终测试中运行良好,如果您发现不正确的结果,那么我将删除我的答案 如果rowID 值实际上是NSNumber 对象但OP 具有NSString 对象,则这是正确的。 这对我有用...值是 NSStrings...为什么它对我有用? 因为数字搜索就是你想要的......【参考方案2】:

您可以按照以下代码进行数字排序:-

NSMutableArray *tmpAr = [[NSMutableArray alloc] init];

NSMutableDictionary *tmpDict = [[NSMutableDictionary alloc] init];
[tmpDict setObject:@"name" forKey:@"number5"];
[tmpDict setObject:@"5" forKey:@"id"];
[tmpAr addObject:tmpDict];

tmpDict = [[NSMutableDictionary alloc] init];
[tmpDict setObject:@"name" forKey:@"number3"];
[tmpDict setObject:@"3" forKey:@"id"];
[tmpAr addObject:tmpDict];

tmpDict = [[NSMutableDictionary alloc] init];
[tmpDict setObject:@"name" forKey:@"number2"];
[tmpDict setObject:@"2" forKey:@"id"];
[tmpAr addObject:tmpDict];

tmpDict = [[NSMutableDictionary alloc] init];
[tmpDict setObject:@"name" forKey:@"number1"];
[tmpDict setObject:@"1" forKey:@"id"];
[tmpAr addObject:tmpDict];

tmpDict = [[NSMutableDictionary alloc] init];
[tmpDict setObject:@"name" forKey:@"number4"];
[tmpDict setObject:@"4" forKey:@"id"];
[tmpAr addObject:tmpDict];

tmpDict = [[NSMutableDictionary alloc] init];
[tmpDict setObject:@"name" forKey:@"number25"];
[tmpDict setObject:@"25" forKey:@"id"];
[tmpAr addObject:tmpDict];

tmpDict = [[NSMutableDictionary alloc] init];
[tmpDict setObject:@"name" forKey:@"number10"];
[tmpDict setObject:@"10" forKey:@"id"];
[tmpAr addObject:tmpDict];

tmpDict = [[NSMutableDictionary alloc] init];
[tmpDict setObject:@"name" forKey:@"number7"];
[tmpDict setObject:@"7" forKey:@"id"];
[tmpAr addObject:tmpDict];

NSLog(@"tmpar1 = %@",tmpAr);

[tmpAr sortUsingComparator:
 ^(id obj1, id obj2)
 
     NSInteger value1 = [[obj1 objectForKey: @"id"] intValue];
     NSInteger value2 = [[obj2 objectForKey: @"id"] intValue];
     if (value1 > value2)
     
         return (NSComparisonResult)NSOrderedDescending;
     

     if (value1 < value2)
     
         return (NSComparisonResult)NSOrderedAscending;
     
     return (NSComparisonResult)NSOrderedSame;
 ];

NSLog(@"tmpar2 = %@",tmpAr);

【讨论】:

【参考方案3】:

试试这样:-

NSDictionary *row1 = [NSDictionary dictionaryWithObjectsAndKeys:@"1",@"rowId",nil];
NSDictionary *row2 = [NSDictionary dictionaryWithObjectsAndKeys:@"2",@"rowId",nil];
NSDictionary *row3 = [NSDictionary dictionaryWithObjectsAndKeys:@"3",@"rowId",nil];

NSMutableArray *arr = [[NSMutableArray alloc] initWithObjects:row1,row2,row3,nil];

NSSortDescriptor *desc = [[NSSortDescriptor alloc] initWithKey:@"rowId" ascending:YES];
[arr sortUsingDescriptors:[NSArray arrayWithObject:desc]];

// before sort
NSLog(@"Before %@",arr);
[arr sortedArrayUsingComparator:^(NSDictionary *item1, NSDictionary *item2) 
    NSString *first = [item1 objectForKey:@"rowId"];
    NSString *second = [item2 objectForKey:@"rowId"];
    return [first compare:second options:NSNumericSearch];
];
// After sort
NSLog(@"After %@",arr);

【讨论】:

这与用户已经在做的事情有什么不同??? 更新还是不正确。这会进行字母排序而不是所需的数字排序。【参考方案4】:

如果您使用initWithKey:ascending:selector:sortDescriptorWithKey:ascending:comparator: 创建排序描述符,则可以指定用于比较对象的选择器。

现在的问题是要传递哪个选择器。好吧,您可以在 NSString 上创建一个 Category 来实现自定义排序函数,该函数根据字符串的数值进行排序。请记住,从文档中:

选择器必须指定一个由 由 keyPath 标识的属性。用于比较的选择器 传递了一个参数,即要与自身进行比较的对象,以及 必须返回适当的 NSComparisonResult 常量。选择器 必须具有与以下相同的方法签名:

- (NSComparisonResult)localizedCompare:(NSString *)aString

指定属性键处的对象,相对于每个对象 集合,必须实现用于创建的比较选择器 排序描述符。如果未指定自定义选择器,则对象必须 实现比较。

【讨论】:

以上是关于使用值对 NSDictionary 的 NSArray 进行排序的主要内容,如果未能解决你的问题,请参考以下文章

从 NSDictionary 检索键/值对会导致数据不正确并崩溃

从给定键值对的字典数组中过滤 NSDictionary

NSDictionary

从 NSDictionaries 数组中获取键/值对

在 Swift 中对 NSDictionary 对象的 NSArray 进行排序

字典NSDictionary和NSMutableDictionary的使用