2016-11-02 18 views
1

の配列。ソート私は数字と文字列の配列を持っている数値と文字列

NSArray* list = @[@"9", @"21", @"A 2-5", @"19-1", @"10", @"D 7-10", @"13-2"]; 

ように私は、この配列が

@[@"9", @"10", @"21", @"13-2", @"19-1", @"A 2-5", @"D 7-10"]; 

としてソートしたいしかし、私は

[list sortedArrayUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) { 
    return [obj1 compare:obj2]; 
}]; 

を使用する場合、私は私が

を使用する場合、私はあまりにも同様の結果を得る

@[@"10", @"13-2", @"19-1", @"21", @"9", @"A 2-5", @"D 7-10"]; 

を取得します

[list sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; 

私は期待通りにはどうすれば結果を達成することができますか?

+2

'return [obj1 compare:obj2 options:NSNumericSearch];'を使用してください。 – rmaddy

+0

さらに良い(y)。 – x4h1d

答えて

1

あなたはsortedArrayUsingComparatorで正しい軌道に乗っていました。ここでは、それを実装する方法です。

NSArray* list = @[@"9", @"21", @"A 2-5", @"19-1", @"10", @"D 7-10", @"13-2"]; 
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init]; 
NSArray *sortedList = [list sortedArrayUsingComparator:^NSComparisonResult(NSString *string1, NSString *string2) { 
     NSNumber *number1 = [numberFormatter numberFromString:string1]; 
     NSNumber *number2 = [numberFormatter numberFromString:string2]; 

     if (number1 && number2) 
      return [number1 compare:number2]; 
     else if (number1) 
      return NSOrderedAscending; 
     else if (number2) 
      return NSOrderedDescending; 
     else return [string1 compare:string2]; 
}]; 
NSLog(@"sortedList: %@", sortedList); 

出力:

( 9、 10、 21、 "13-2"、 "19-1"、 「 2-5" 、 "D 7-10")

あなたがintegerValue代わりのを使用できない理由0の場合は、たとえば13-213として解析し、21より前になります。これは期待どおりではありません。 NSNumberFormatterは少し柔軟性があり、文字列が正確に数字でない場合はnilを返します。

+0

あなたが言及したように、整数値に変換しようとしていました。ありがとう。 – x4h1d

+0

これは、ソートを実行するのが最も難しい方法です。 – rmaddy

+0

@rmaddyあなたは私に無知を感じさせます:) – alexburtnik

0

には「数字と文字列の配列」がありません。問題の配列はStringsです。それらは文字シーケンスに基づいて比較されます:最初の文字が同じ場合は比較し、2番目の文字を比較します。

指定した注文が必要な場合は、カスタムコンパレータ/ソート方法を実装する必要があります(this answerは可能性をうまく示しています)。

関連する問題