对包含 NSNumber 变量的 NSobjects 的 NSArray 进行排序

Posted

技术标签:

【中文标题】对包含 NSNumber 变量的 NSobjects 的 NSArray 进行排序【英文标题】:Sort NSArray of NSobjects that contain NSNumber variables 【发布时间】:2014-03-01 07:24:32 【问题描述】:

我有一个由两个文本字段组成的对象类的 NSArray。我想按升序对这些对象进行排序,之前我已经使用 NSDictionary 对象完成了此操作,但是我现在已经更改为我创建的对象类,所以我真的不知道如何比较值以获取排序后的数组。

对象变量是NSNumbers,但只包含数字值,我认为这会影响事情。

这就是我使用旧代码对 NSDictionary 值进行排序的方式。

 NSArray *tempSortedItemsArray = [installArray sortedArrayUsingDescriptors:
                            @[[NSSortDescriptor
                               sortDescriptorWithKey:@"first" ascending:YES],
                            [NSSortDescriptor
                             sortDescriptorWithKey:@"second" ascending:YES]]];

    sortedItemsArray = [tempSortedItemsArray mutableCopy];
    tempSortedItemsArray = nil;

所以如果我有一个这样的对象数组

(第一/第二)

2 1
0 0 
1 0
1 1
2 2
2 0
3 0

如果会这样排序

0 0
1 0
1 1
2 0
2 1
2 2 
3 0

对于使用 NSNumber 变量 first 和 second 调整 NSObject 类的任何帮助将不胜感激。

【问题讨论】:

为什么要对包含文本字段的对象数组进行排序?为什么自定义对象不只包含数据?我认为你在做一些奇怪的事情。 【参考方案1】:
[arr sortUsingComparator:^NSComparisonResult(id obj1, id obj2) 
   NSString *first=[NSString stringWithFormat:@"%d%d",obj1.num1.intValue,obj1.num2.intValue];
 NSString *second=[NSString stringWithFormat:@"%d%d",obj2.num1.intValue,obj2.num2.intValue];
    return [first compare:second options:NSNumericSearch];

];

【讨论】:

哎呀,对象变量实际上是 NSNumbers,你能看看我更新的问题吗? 这不太管用尝试 啊,我看到你更新了,因为我发布了我的最后一条评论,现在可以测试了! 为什么要在这里使用字符串比较而不只是比较数字?【参考方案2】:

你可以使用NSArray的其他排序方式如:

sortedArrayUsingFunction:context: sortedArrayUsingSelector: sortedArrayUsingComparator:

【讨论】:

也许您应该提供这些方法的一些示例用法?【参考方案3】:

给定一个像这样工作的对象:

@interface Object : NSObject

@property (copy) NSNumber *first;
@property (copy) NSNumber *second;

+(Object *)objectWithWithFirst:(NSNumber *)first second:(NSNumber *)second;

@end


@implementation Object

+(Object *)objectWithWithFirst:(NSNumber *)first second:(NSNumber *)second 
    Object *object = [[Object alloc] init];
    object.first = first;
    object.second = second;
    return object;



-(NSString *)description 
    return [NSString stringWithFormat:@"%@ %@", _first, _second];


@end

你可以排序

NSArray *sorted = [array sortedArrayUsingComparator:^NSComparisonResult(Object *obj1, Object *obj2) 
    NSComparisonResult result = [obj2.second compare:obj2.second];
    if (result == NSOrderedSame)
        result = [obj1.first compare:obj2.first];
    return result;
];

例子:

int main(int argc, const char * argv[])


    @autoreleasepool 

        NSArray *array = @[
                           [Object objectWithWithFirst:@2 second:@1],
                           [Object objectWithWithFirst:@0 second:@0],
                           [Object objectWithWithFirst:@1 second:@0],
                           [Object objectWithWithFirst:@1 second:@1],
                           [Object objectWithWithFirst:@2 second:@2],
                           [Object objectWithWithFirst:@2 second:@0],
                           [Object objectWithWithFirst:@3 second:@0]
                           ];

        NSLog(@"%@", array);

        NSArray *sorted = [array sortedArrayUsingComparator:^NSComparisonResult(Object *obj1, Object *obj2) 
            NSComparisonResult result = [obj2.second compare:obj2.second];
            if (result == NSOrderedSame)
                result = [obj1.first compare:obj2.first];
            return result;
        ];

        NSLog(@"%@", sorted);
    
    return 0;

这将在您的示例数据上完美运行。当然,您可以将比较器代码直接放入您的 Object 类中 - 清理更多。

【讨论】:

【参考方案4】:

如果您的自定义类具有firstsecond 属性,那么您发布的代码就可以正常工作。

NSNumbers 已经知道如何将自己与其他数字进行比较。 NSSortDesvriptors 适用于任何实现键值编码读取部分的对象。对于任何遵循普通约定的属性,所有NSObject 子类都会自动这样做。 @propertys 遵循普通约定。

【讨论】:

以上是关于对包含 NSNumber 变量的 NSobjects 的 NSArray 进行排序的主要内容,如果未能解决你的问题,请参考以下文章

iOS NSNumber转化NSString之description

Swift 无法将 NSNumber 桥接到 Float [重复]

休息套件。如何在 NSObject 中发布 NSDictionary

为 NSNumber 值设置精度

如何通过 NSObject 子类上的 @properties 简洁地迭代以从 plist 设置属性?

对NSNumber的理解