私は Person NSDictionary を持っています。そのキーは人の名前であり、オブジェクトは 2 つのキーを持つ NSDictionary です: 彼のニックネーム (NSString) と彼の年齢 (NSNumber)。
最年少と最年長の人の名前を取得できるように、年齢の昇順で並べ替えられた Person 辞書を作成したいと思います。それを行う最良の方法は何ですか?
ありがとう!
私は Person NSDictionary を持っています。そのキーは人の名前であり、オブジェクトは 2 つのキーを持つ NSDictionary です: 彼のニックネーム (NSString) と彼の年齢 (NSNumber)。
最年少と最年長の人の名前を取得できるように、年齢の昇順で並べ替えられた Person 辞書を作成したいと思います。それを行う最良の方法は何ですか?
ありがとう!
NSDictionary には、アイテムを値でソートし、ソートされたキーを取得するための便利なメソッドがいくつか定義されています。
ドキュメントを参照してください。
keysSortedByValueUsingComparator:
keysSortedByValueUsingSelector:
keysSortedByValueWithOptions:usingComparator:
あなたは最新の Objective-C 構文を使用しており、年齢は実際には数字で表されていると思います。外観は次のとおりです。
[people keysSortedByValueUsingComparator:(NSDictionary *firstPerson, NSDictionary *secondPerson) {
return [firstPerson[@"age"] compare:secondPerson[@"age"]];
}];
ソートされた辞書を提供する言語もありますが、標準NSDictionary
は本質的にソートされていません。すべてのキーを取得し、キー配列を並べ替えてから、並べ替えられたキーに従って辞書をたどることができます。(NSDictionary
私が知らなかったこのユースケースにはいくつかの便利な方法があります。Anuragの回答を参照してください。)
あなたのケースはもう少し複雑です。それを解決する1つの方法は、年齢を名前にマッピングする一時辞書を導入することです。ただし、最小年齢と最大年齢の後にのみいる場合は、すべての人を反復処理して、最大および最小の年齢と名前を追跡します。
NSString *oldestName = nil;
float maxAge = -1;
for (NSString *name in [persons allKeys]) {
NSDictionary *info = persons[name];
float age = [info[@"age"] floatValue];
if (age > maxAge) {
oldestName = info[@"nick"];
maxAge = age;
}
}
そして、辞書をソートするという考えに戻ると、次のように動作する可能性があります。
NSArray *peopleByAge = [people keysSortedByValueUsingComparator:^(id a, id b) {
// Again, see Anurag’s answer for a more concise
// solution using the compare: method on NSNumbers.
float ageA = [a objectForKey:@"age"];
float ageB = [b objectForKey:@"age"];
return (ageA > ageB) ? NSOrderedDescending
: (ageB > ageA) ? NSOrderedAscending
: NSOrderedSame;
}];
@Zoul が言ったように、標準の NSDictionary はソートされていません。
並べ替えるには、配列を使用できます。私はそのようなことを行います
//the dictionary is called dict : in my case it is loaded from a plist file
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
//make a dicoArray that is sorted so the results are sorted
NSArray *dicoArray = [[dict allKeys] sortedArrayUsingComparator:^(id firstObject, id secondObject) {
return [((NSString *)firstObject) compare:((NSString *)secondObject) options:NSNumericSearch];
}];
すべての並べ替えオプションについては、ヘルプを確認してください。提示されたケースでは、辞書は数値として扱われるキーでソートされます(これは私の場合でした)。
別の方法でソートする必要がある場合、ソート可能なリストは次のとおりです。
enum {
NSCaseInsensitiveSearch = 1,
NSLiteralSearch = 2,
NSBackwardsSearch = 4,
NSAnchoredSearch = 8,
NSNumericSearch = 64,
NSDiacriticInsensitiveSearch = 128,
NSWidthInsensitiveSearch = 256,
NSForcedOrderingSearch = 512,
NSRegularExpressionSearch = 1024
};
セレクターによってソートされたキーを返すNSDictionary のメソッドを見てください。そのような方法は複数あります。ソートされたキーの配列を取得し、最初と最後にアクセスして、最年少と最年長の人を取得します。