2013-05-02 35 views
0

我有一个简单的NSArray,其中包含NSNumber s。按升序对NSArray中的数字进行排序,但在末尾发送零。

我这样排序按升序排列:

NSSortDescriptor *lowestToHighest = [NSSortDescriptor sortDescriptorWithKey:@"self" ascending:YES]; 
[_scores sortUsingDescriptors:[NSArray arrayWithObject:lowestToHighest]]; 

我的问题是,我想包含0是在末尾,而不是在开始NSNumber秒。这里是我可能要排序的类型的数组(包含一些空NSNumber的只有我的例子):

0 
25 
12 
0 
8 
0 

我的课程的代码进行排序的数组是这样的:

0 
0 
0 
8 
12 
25 

我会就像是这样的:

8 
12 
25 
0 
0 
0 

当然,我可以用0去除线,并在年底将他们重新排序它手动,但我在寻找最干净的小号解决方案可能。

+0

'8,12,0'是按升序还是降序排列?你是如何将'nil'存储在'NSArray'中的?或者你确定你有'NSNumber'实例吗?他们不是'NSString'吗? – 2013-05-02 12:48:35

+0

@ H2CO3对作者如何在NSArray中表示NSNumber的方式设法存储无值进行了约定 – 2013-05-02 12:50:16

+0

除了数值** 0 **之外,它是递增顺序,发送到数组的末尾。事实上,它们不是“零”对象,而是非初始化的NSNumbers。在调试控制台中显示为** [5] id \t 0x00000000 ** – rdurand 2013-05-02 12:51:11

回答

13

排序使用comparator阵列。

NSArray *sortedArray = [array sortedArrayUsingComparator: ^(id obj1, id obj2) { 

    if ([obj1 integerValue] == 0 && [obj2 integerValue] == 0) 
    { 
     return (NSComparisonResult)NSOrderedSame; 
    } 
    if ([obj1 integerValue] == 0) 
    { 
     return (NSComparisonResult)NSOrderedDescending;    
    } 
    if ([obj2 integerValue] == 0) 
    { 
     return (NSComparisonResult)NSOrderedAscending; 
    } 

    if ([obj1 integerValue] > [obj2 integerValue]) 
    { 
     return (NSComparisonResult)NSOrderedDescending; 
    } 

    if ([obj1 integerValue] < [obj2 integerValue]) 
    { 
     return (NSComparisonResult)NSOrderedAscending; 
    } 
    return (NSComparisonResult)NSOrderedSame; 
}]; 
+0

看起来像我在找什么..谢谢!我想过使用比较器,但无法使其工作。 – rdurand 2013-05-02 12:58:27

+0

没有声明这个代码的部分 – 2015-05-19 08:51:40

+0

@gokhancokkececi你的意思是id1和id2 - 这显然是一个错字,现在已修复。 – JeremyP 2015-05-19 15:52:55

1

方法1:

  • 步骤1:对数组进行排序。

  • 第2步:将零移动到数组的末尾。

方法2:

  • 步骤1:写一个比较器功能的订单0之后任何其它值。

  • 第2步:对数组进行排序。

+0

谢谢,但那不是我要找的正如我在我的问题中所说的那样。 – rdurand 2013-05-02 12:54:23

+0

@Monolo:当我发表我的评论时,Caleb只提出了第一种方法。我在我的问题中说过,我知道我可以做到这一点,但我一直在寻找比“排序然后移动零”更干净的东西。方法2正是JeremyP在他的回答中所说的,在迦勒编辑自己的答案之前出现了。 – rdurand 2013-05-02 13:10:42

4

这将解决您的问题,

NSArray *sortedScores = [_scores sortedArrayUsiHelperComparator:^(id obj1, id obj2){ 
    if([obj1 integerValue]==0 && [obj2 integerValue]==0){ 
     return (NSComparisonResult) NSOrderedSame; 
    }else if([obj1 integerValue]==0){ 
     return (NSComparisonResult) NSOrderedDescending; 
    }else if([obj2 integerValue]==0){ 
     return (NSComparisonResult) NSOrderedAscending; 
    } 
    if([obj1 integerValue] >[obj2 integerValue]) return (NSComparisonResult) NSOrderedDescending; 
    if([obj1 integerValue] <[obj2 integerValue]) return (NSComparisonResult) NSOrderedAscending; 
    return (NSComparisonResult) NSOrderedSame; 

}]; 
+0

谢谢,但我认为JeremyP的回答更准确,因为他比较* [id1 integerValue] == 0 *而不是* obj1 == nil *。在我的情况下,我想要零到最后,而不是零对象。 – rdurand 2013-05-02 12:57:17

+0

在你的问题中,有零值。我为此编写了代码。你改变了这个问题。现在检查! – 2013-05-02 12:59:55

+0

无论如何,你不能把'nil'放在'NSArray'中。 – JeremyP 2013-05-02 13:02:17

0

您可以使用NSPredicate过滤你不想要的值..

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self > 0"]; 
NSMutableArray *filteredArray = [[_scores filteredArrayUsingPredicate:predicate] mutableCopy]; 
NSSortDescriptor *lowestToHighest = [NSSortDescriptor sortDescriptorWithKey:@"self" ascending:YES]; 
[filteredArray sortUsingDescriptors:[NSArray arrayWithObject:lowestToHighest]]; 
+2

谢谢,但我相信这将删除所有的零,对不对?我想让他们在阵列中,但最后。无论如何,这对未来可能会很好。 – rdurand 2013-05-02 13:02:55

+0

@rdurand是代码将删除1行中低于0的所有值。之后它会根据您想要的顺序进行排序。 – 2013-05-02 13:09:13

1

@ JeremyP的答案提供了适当的整理,也可能是你所追求的。

然而,对于完整性的方式与过滤器和标准compare:方法来做到这一点:

NSArray *numbers = @[@12, @0, @10, @15, @0, @3]; 

NSArray *sortedPositiveNumbers = [[numbers filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self > 0"]] sortedArrayUsingSelector:@selector(compare:)]; 
NSArray *zeroes = [numbers filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self = 0"]]; 

NSArray *result = [sortedPositiveNumbers arrayByAddingObjectsFromArray:zeroes]; 

感谢迦勒的火花。

+0

感谢您的回答! – rdurand 2013-05-02 14:40:32