【问题标题】:Algorithm: Keeping count of key/value pair in NSDictionary算法:保持 NSDictionary 中键/值对的计数
【发布时间】:2010-09-23 09:20:52
【问题描述】:

作为 Cocoa 的新手,并且可能不知道所有已经具有此功能的可用类,这些类已经整齐地包装在 OO 类中,这里有一个算法查询。计算特定键在多个 NSDictionary 实例的数组中出现的次数的最佳选择是什么?

基本上我的数据结构(在本例中为NSArray)可能在任何给定时间包含多个NSDictionary 实例,每个实例具有相同的键,可能具有不同的值。一些值重复。我希望能够知道特定键/值出现了多少次。示例:

{
  foo => 1,
  bar => 2
}
{
  foo => 1,
  bar => 3
}
{
  foo => 2,
  bar => 1
}

在这种情况下,我感兴趣的是 foo=>1 出现了 2 次,foo=>2 出现了 1 次。构建NSCountedSet 的实例是解决此问题的最佳方法吗?也许是 C 链表?

【问题讨论】:

    标签: iphone c objective-c cocoa algorithm


    【解决方案1】:

    您可能需要重新考虑如何构建数据。我会在添加到 NSArray 时跟踪这样的事情,而不是在以后尝试发现它。您可以创建一个新类来处理添加和删除数据,以便您可以保留自己的数据计数。

    【讨论】:

      【解决方案2】:
      NSDictionary * dict1 = [[NSDictionary alloc] initWithObjectsAndKeys:
                              [NSNumber numberWithInt:1], @"foo",
                              [NSNumber numberWithInt:2], @"bar", nil];
      NSDictionary * dict2 = [[NSDictionary alloc] initWithObjectsAndKeys:
                              [NSNumber numberWithInt:1], @"foo",
                              [NSNumber numberWithInt:3], @"bar", nil];
      NSDictionary * dict3 = [[NSDictionary alloc] initWithObjectsAndKeys:
                              [NSNumber numberWithInt:2], @"foo",
                              [NSNumber numberWithInt:1], @"bar", nil];
      NSArray * arrayOfDictionaries = [[NSArray alloc] initWithObjects:
                                       dict1, dict2, dict3, nil];
      
      // count all keys in an array of dictionaries (arrayOfDictionaries):
      
      NSMutableDictionary * countKeys = [[NSMutableDictionary alloc] initWithCapacity:0];
      NSCountedSet * counts = [[NSCountedSet alloc] initWithCapacity:0];
      
      NSArray * keys;
      NSString * pairString;
      NSString * countKey;
      for (NSDictionary * dictionary in arrayOfDictionaries)
      {
          keys = [dictionary allKeys];
          for (NSString * key in keys)
          {
              pairString = [NSString stringWithFormat:@"%@->%@", key, [dictionary valueForKey:key]];
              if ([countKeys valueForKey:pairString] == nil)
              {
                  [countKeys setValue:[NSString stringWithString:pairString] forKey:pairString];
              }
              countKey = [countKeys valueForKey:pairString];
              { [counts addObject:countKey]; }
          }
      }
      
      NSLog(@"%@", counts);
      
      [counts release];
      [countKeys release];
      
      [arrayOfDictionaries release];
      [dict1 release];
      [dict2 release];
      [dict3 release];

      【讨论】:

      • 呸!这比我想象的要困难得多。正如 Brian C. Lane 所说,您可能需要重新考虑这是如何实现的。
      • 谢谢詹姆斯。我不知道 NSCountedSet 存在。希望在希勒加斯的书中提到它。 :-) 干杯!
      • eJames:你自己在做你不需要的工作。看我的回答:stackoverflow.com/questions/307695/…
      【解决方案3】:
      NSCountedSet *keyCounts = [NSCountedSet set];
      for (NSDictionary *dict in myDictionaries)
          [keyCounts unionSet:[NSSet setWithArray:[dict allKeys]]];
      

      【讨论】:

      • 我第一次也犯了这个错误。他实际上想要唯一对的计数,而不仅仅是键的计数。如果其中一个字典对于键“foo”的值为 2,而另一个字典对于同一键的值为 3,则应计为集合中的两个唯一条目。
      • 是的,我知道。我对您的条目的回应比最初的问题更多。原始集合更难解决原始问题。我认为,制作模型对象会更好地为他服务。
      • 您可能对模型对象是正确的。感谢您对我的代码的提醒。我最初没有考虑 NSCountedSet,但我可以看到你的 sn-p 会很有用。对这个答案的反对不是我的,但现在得到了我的支持。
      猜你喜欢
      • 1970-01-01
      • 2014-09-25
      • 1970-01-01
      • 2018-09-22
      • 1970-01-01
      • 1970-01-01
      • 2013-03-18
      • 2012-05-15
      • 1970-01-01
      相关资源
      最近更新 更多