【问题标题】:Sort an NSDictionary into an NSMutableArray but keep value and key?将 NSDictionary 排序为 NSMutableArray 但保留值和键?
【发布时间】:2012-11-30 10:19:58
【问题描述】:

我有点困惑:试图获取我在 NSDictionary 中的球员姓名和分数列表,并将它们按分数顺序排序(最高分在前)。我知道我不能对字典进行排序,所以我需要先将数据移动到一个数组中,但是这样做,我不会丢失每个字典键/值对的一半吗?

例如,假设我有以下对:

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

如果我去把分数拿出来排序,然后再取回钥匙,约翰和斯坦不会因为他们的分数相同而混淆吗?它可能会调用其中一个两次,等等?

我意识到我无法对字典进行排序,但有更聪明的方法吗?

【问题讨论】:

    标签: objective-c sorting nsarray nsdictionary


    【解决方案1】:

    您可以做的是根据他们的分数获得一个排序的玩家数组,然后为每个玩家创建一个字典并将它们附加到另一个数组中。可能是这样的(我正在使用新的文字语法,如果合适的话使用旧的):

    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 类并将其数据(分数、名称等)作为属性。

    【讨论】:

    • 这确实有效,但您能否澄清for 循环在这里的工作原理?我觉得语法让我有点困惑,这是新东西吗(@{} 块?)
    • @{} 只是一个 NSDictionary 文字。扩展后的代码如下所示:[NSDictionary dictionaryWithObjectsAndKeys: p, @"name", [scores valueForKey:p], @"score", nil];。我希望这是有道理的...有关 ObjC 文字的更多信息,请查看此处:clang.llvm.org/docs/ObjectiveCLiterals.html
    【解决方案2】:

    您必须创建两个数组,一个用于得分,另一个用于播放器。关键是玩家数组与(排序的)分数数组的顺序相同。下面的实现假设您使用NSNumber 对象保留分数,并且效率不是特别高,因为它对值进行了两次排序:

    (未经测试)

    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];
    }];
    

    【讨论】:

    • 这会引发大量错误。不希望看到 NSComparisonResult 等。如果我按分数排序,我不能按相同的东西对另一个排序,可以吗?我的意思是,如果我将名称和分数分成两个数组并对其中任何一个进行排序,它们就会立即不同步,不是吗?
    • 不,因为您正在使用他们的分数 (keysSortedByValueUsingComparator:) 对字典中的玩家进行排序。我会修复语法错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-03
    • 1970-01-01
    • 2013-09-24
    • 2016-07-04
    相关资源
    最近更新 更多