【问题标题】:Finding minimum and maximum values in a nested NSDictionary在嵌套的 NSDictionary 中查找最小值和最大值
【发布时间】:2012-12-05 07:47:35
【问题描述】:

我有一个 Person NSDictionary,它的键是这个人的名字,对象是一个 NSDictionary,它有两个键:他的昵称 (NSString) 和他的年龄 (NSNumber)。

我想得到按年龄升序排序的 Person 字典,这样我就可以得到最年轻和最年长的人的名字。 最好的方法是什么?

谢谢!

【问题讨论】:

    标签: objective-c sorting nsdictionary


    【解决方案1】:

    在 NSDictionary 中定义了一些方便的方法来按值对项目进行排序并取回排序后的键。

    查看文档,

    keysSortedByValueUsingComparator:
    keysSortedByValueUsingSelector:
    keysSortedByValueWithOptions:usingComparator:
    

    我猜您使用的是现代 Objective-C 语法,而年龄实际上是用数字表示的。下面是它的外观:

    [people keysSortedByValueUsingComparator:(NSDictionary *firstPerson, NSDictionary *secondPerson) {
        return [firstPerson[@"age"] compare:secondPerson[@"age"]];
    }];
    

    【讨论】:

    • 谢谢!您的答案也有效.. 不幸的是,无法将两个答案标记为已接受:)
    【解决方案2】:

    某些语言提供排序字典,但标准 NSDictionary 本质上是未排序的。您可以获取所有键,对键数组进行排序,然后根据排序后的键遍历字典。 (NSDictionary 有几种我不知道的用例的便捷方法,请参阅 Anurag 的回答。)

    您的情况有点复杂,解决它的一种方法是引入一个临时字典,将年龄映射到名称。但是,如果您只是在最小和最大年龄之后,只需遍历所有人并跟踪最大和最小年龄和姓名:

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

    【讨论】:

    • 你的意思是手动排序?是否有任何方便的方法可以做到这一点,也许使用自定义比较器?
    • NSArray 有几种排序方法,但请参阅我的编辑 - 在您的情况下,最好忘记排序。
    【解决方案3】:

    正如@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
    };
    

    【讨论】:

      【解决方案4】:

      iOS 9.2

      // NSNumbers 字典

      NSDictionary * phoneNumbersDict = @{@"400-234-090":67,@"701-080-080":150};
      

      // 升序

          NSArray * keysArraySortedByValue = [phoneNumbersDict keysSortedByValueUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
                  return [obj1 compare:obj2];
              }];
      
      //按降序排列
      NSArray * keysArraySortedByValue = [phoneNumbersDict keysSortedByValueUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
                      return [obj2 compare:obj1];
                  }];
      

      这是 NSComparisonResults 的枚举。

      enum {
         NSOrderedAscending = -1,
         NSOrderedSame,
         NSOrderedDescending
      };
      typedef NSInteger NSComparisonResult;
      

      【讨论】:

        【解决方案5】:

        查看返回由选择器排序的键的NSDictionary's method。这样的方法不止一种。你得到一个排序的键数组,然后访问第一个和最后一个,得到你最小和最年长的人。

        【讨论】:

          猜你喜欢
          • 2019-04-22
          • 1970-01-01
          • 1970-01-01
          • 2012-09-16
          • 2013-11-12
          • 1970-01-01
          • 2017-04-20
          • 1970-01-01
          • 2018-05-03
          相关资源
          最近更新 更多