2

私は少し混乱しています。NSDictionaryにあるプレーヤー名とスコアのリストを取得し、それらをスコア順に並べ替えようとしています(最高スコアが最初)。辞書を並べ替えることができないので、最初にデータを配列に移動する必要がありますが、そうすることで、各辞書のキーと値のペアの半分を失う必要はありませんか?

たとえば、次のペアがあるとします。

Bill / 10000
John / 7500
Stan / 7500
Mark / 5000

スコアを取り出して並べ替えてから、後でキーを取得すると、ジョンとスタンは同じスコアだったので混乱しませんか?そのうちの1つを2回呼び出すなど、可能性がありますか?

辞書を並べ替えることができないことに気づきましたが、これを行うためのより賢い方法はありますか?

4

2 に答える 2

4

できることは、スコアに基づいてプレーヤーの並べ替えられた配列を取得し、各プレーヤーの辞書を作成して別の配列に追加することです。おそらく次のようなものです(私は新しいリテラル構文を使用していますが、必要に応じて古いものを使用してください):

NSDictionary *scores = @{
    @"Stan" : @7500,
    @"Mark" : @5000,
    @"John" : @7500,
    @"Bill" : @10000
};

NSArray *sp = [scores keysSortedByValueUsingComparator:^(id obj1, id obj2){
    return [obj2 compare:obj1];
}];

NSMutableArray *players = [NSMutableArray arrayWithCapacity:0];
for (NSString *p in sp) [players addObject:@{ @"name":p, @"score":scores[p] }];

今、あなたのplayers配列は次のとおりです。

(
        {
        name = Bill;
        score = 10000;
    },
        {
        name = John;
        score = 7500;
    },
        {
        name = Stan;
        score = 7500;
    },
        {
        name = Mark;
        score = 5000;
    }
)

PS。キーがプレーヤー名である辞書を保持するのは良い考えではありません.2人の異なるJohnプレーヤーがいると考えてください...その場合はどうなりますか? また、より良い解決策は、Playerクラスを作成し、そのデータ (スコア、名前など) をプロパティとして保持することです。

于 2012-11-30T10:58:44.543 に答える
0

スコア用とプレイヤー用の 2 つの配列を作成する必要があります。重要な点は、プレイヤー配列が (ソートされた) スコア配列と同じ順序であるということです。以下の実装は、オブジェクトを使用してスコアを保持することを前提としてNSNumberおり、値を 2 回ソートするため特に効率的ではありません。

(未テスト)

NSDictionary *dict = ...;    // key=player (NSString), value=score (NSNumber).

NSArray *scores = [[dict allValues] sortedArrayUsingComparator:^(id obj1, id obj2) {
    return [(NSNumber *)obj2 compare:(NSNumber *)obj1];
}];

NSArray *players = [dict keysSortedByValueUsingComparator:^(id obj1, id obj2) {
    return [(NSNumber *)obj2 compare:(NSNumber *)obj1];
}];
于 2012-11-30T10:34:33.173 に答える