NSArray按功能排序

时间:2012-10-30 14:19:26

标签: objective-c nsarray sorting

我有一个包含多个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;

}];

7 个答案:

答案 0 :(得分: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

答案 1 :(得分: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]];
}];

您可以找到更多比较方法:

How to sort an NSMutableArray with custom objects in it?

答案 2 :(得分:0)

您寻找的方法系列以sortedArray为前缀。

对于功能(这是多个选项之一),请参阅:-[NSArray sortedArrayUsingFunction:context:]

答案 3 :(得分:0)

编辑:如果你想rating除以numberOfVotes,你必须按功能或比较器块排序或用模型对象替换字典有一种计算rating / numberOfVotes的方法。

使用NSSortDescriptor

 NSArray *sorted = [array sortedArrayUsingDescriptors:[NSArray arrayWithObjects:
    [NSSortDescriptor sortDescriptorWithKey:@"rating" ascending:YES],
    [NSSortDescriptor sortDescriptorWithKey:@"numberOfVotes" ascending:YES],
    nil]
 ];

答案 4 :(得分:0)

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

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

  1. NSPredicate

    您可以看到示例here

  2. NSSortDescriptor

    您可以看到示例here

  3. 正则表达式

  4. 设置操作

  5. 键值编码

答案 5 :(得分:0)

理想情况下,您应该使用自定义对象替换NSDictionary,其中包含ratingnumberOfVotes等属性。然后,您可以在此自定义对象上声明方法compare:,并将其用作对数组进行排序的选择器。

您可以使用块代码对对象进行排序,但将实现抽象为自定义对象要清晰得多。

答案 6 :(得分:0)

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

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

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