2

我有一个NSArray包含几个NSDictionary实例。NSDictionary在其他字段中,每个都有一个名为的对象rating和一个numberOfVotes(两者都是int)。如何对数组进行排序,使其按rating/排序numberOfVotes?更一般地说,我可以通过执行上述操作对其进行排序吗?或者将每个操作的值添加到每个对象NSDictionary然后按此排序会更好吗?

谢谢

编辑 - 我添加了以下内容。仍然没有正确排序。一个问题:这是否适用于我的数组中的 2 个以上的对象。(对象的数量会有所不同)

    [sortedArray sortedArrayUsingComparator:^NSComparisonResult(id dict1, id dict2)
{
    MyObj *obj1 = (MyObj *)dict1;
    MyObj *obj2 = (MyObj *)dict2;

    int rating1 = obj1.rating.intValue;
    int rating2 = obj2.rating.intValue;

    int number1 = obj1.number_of_votes.intValue;
    int number2 = obj2.number_of_votes.intValue;

    double key1 = ((double)rating1)/number1;
    double key2 = ((double)rating2)/number2;

    if (key1 < key2)
    {
        return NSOrderedDescending;
    }

    if (key2 < key1)
    {
        return NSOrderedAscending;
    }
    return NSOrderedSame;

}];
4

7 回答 7

4

您可以定义一个自定义比较器以使用您正在寻找的那种复合排序键。如果没有充分的理由在字典中使用该排序键,则除了执行排序之外,不要向字典中添加项目。

array = [array sortedArrayUsingComparator: ^(id obj1, id obj2) {
    int rating1 = [[obj1 objectForKey:@"rating"] intValue];
    int numberOfVotes1 = [[obj1 objectForKey:@"numberOfVotes"] intValue];
    int rating2 = [[obj2 objectForKey:@"rating"] intValue];
    int numberOfVotes2 = [[obj2 objectForKey:@"numberOfVotes"] intValue];
    double key1 = ((double)rating1)/numberOfVotes1;
    double key2 = ((double)rating2)/numberOfVotes2;
    if (key1 > key2) {
        return (NSComparisonResult)NSOrderedDescending;
    }

    if (key1 < key2) {
        return (NSComparisonResult)NSOrderedAscending;
    }
    return (NSComparisonResult)NSOrderedSame;
}];

注意:sortedArrayUsingComparator:方法不对数组进行就地排序;相反,它返回一个排序的副本。如果您想要就地排序,请使用NSMutableArray.

于 2012-10-30T14:29:16.953 回答
1

适当的方法是使用这样的块

NSArray *sortedArray;

sortedArray = [unsortedArray sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
    float first = [[(NSDictionary*)a objectForKey:@"rating"] floatValue]/
                      [[(NSDictionary*)a objectForKey:@"numberOfVotes"] floatValue];
    float second = [[(NSDictionary*)a objectForKey:@"rating"] floatValue]/
                      [[(NSDictionary*)a objectForKey:@"numberOfVotes"] floatValue];
return [[NSNumber numberWithFloat:first] compare: [NSNumber numberWithFloat:second]];
}];

您可能会找到更多比较方法:

如何对包含自定义对象的 NSMutableArray 进行排序?

于 2012-10-30T14:32:20.267 回答
0

理想情况下,您应该使用具有和NSDictionary等属性的自定义对象替换。然后,您可以在此自定义对象上声明一个方法并用作选择器来对数组进行排序。ratingnumberOfVotescompare:

您可以使用块代码对对象进行排序,但将实现抽象为自定义对象会更简洁。

于 2012-10-30T14:36:01.037 回答
0

您可以在此处使用 NSSortDescriptor 进行排序,例如包含多个 NSDictionnaries 名称的数组是 dataArray。

 NSSortDescriptor * descriptor = [[NSSortDescriptor alloc] initWithKey:rating
                            ascending:YES];
 NSArray * keyArrray = [NSArray arrayWithObjects:descriptor, nil];
 NSArray * sortedArray = [dataArray sortedArrayUsingDescriptors:keyArrray];

在 NSSortDescriptor 的帮助下,我们可以对任何数据类型的键值对进行排序。

于 2012-10-30T14:43:58.620 回答
0

过滤数据是计算中的基本任务之一。

您可以通过多种方式对其进行排序。

  1. NS谓词

    您可以在此处查看示例

  2. NSSortDescriptor

    您可以在此处查看示例

  3. 常用表达

  4. 设置操作

  5. 键值编码

于 2012-10-30T14:35:04.110 回答
0

您寻求的方法系列以sortedArray.

对于函数(它是多个选项之一),请参阅:-[NSArray sortedArrayUsingFunction:context:]

于 2012-10-30T14:27:35.127 回答
0

编辑:如果要rating除以numberOfVotes,则必须按函数或比较器块进行排序,或者将字典替换为具有计算方法的模型对象rating / numberOfVotes

使用NSSortDescriptor.

 NSArray *sorted = [array sortedArrayUsingDescriptors:[NSArray arrayWithObjects:
    [NSSortDescriptor sortDescriptorWithKey:@"rating" ascending:YES],
    [NSSortDescriptor sortDescriptorWithKey:@"numberOfVotes" ascending:YES],
    nil]
 ];
于 2012-10-30T14:29:01.477 回答