【问题标题】:Sort array of dictionaries according to separate array ?根据单独的数组对字典数组进行排序?
【发布时间】:2014-03-21 13:41:18
【问题描述】:

我有一个奇怪的问题。所以我有一系列字典说,

(
Dict 1:
"Name" = "B"
"Number" = "2"

Dict 2:
"Name" = "A"
"Number" = "1"

Dict 3:
"Name" = "D"
"Number" = "4"

Dict 4:
"Name" = "C"
"Number" = "3"

Dict 5
"Name" = "E"
"Number" = "5"
)

假设我有一个数组:

(
"1"
"4"
"2"
)

如何获得一个数组,其中包含其“数字”键与该数组中的每个对象匹配的所有字典,并根据第二个数组对其进行排序?

例如输出将是

(
Dict 1:
"Name" = "A"
"Number" = "1"

Dict 2:
"Name" = "D"
"Number" = "4"

Dict 3:
"Name" = "B"
"Number" = "2"
)

我想我可以使用sortedArrayUsingDescriptors,但我不确定如何指定多个描述符。描述符可以包含数组中的每个对象吗? 非常感谢任何帮助或指导。

【问题讨论】:

  • 如何执行这 2 个步骤: 1. 使用 key = number 对原始字典进行排序 2. 对于数组 {1,4,2..} 中的每个数字,在排序后的字典中执行 bsearch,如果找到,则打印该条目的详细信息复杂度 = O(mlogm + nlogm) m = 字典大小,n = 查询数组大小
  • 哦,但这里有些不清楚,你的字典会有两个相同编号的条目吗?例如: Dict 1 { Name = A, number = 1} Dict 2 {Name = B, number = 1} 如果是,那么当您的查询数组中有 1 时,我应该将两者都打印出来吗?
  • @shole bsearch 是什么意思?你的意思是排序数组而不是字典?
  • @shole 不,数字键中不会有重复项。
  • 我的意思是二分搜索,你能重新排列你的字典,让它随数字升序吗?例如,我可以制作成对数组 [(1,2), (2,1), (3,4), (4,3),(5,5)],其形式为 (DictID, Number) ,然后将其重新排序为 [(2,1),(1,2),(4,3),(3,4),(5,5)]。最后对每个查询进行二分搜索,比如查询 {1,4,2},我可以分别找到 (2,1), (3,4), (1,2),所以你知道你应该打印 Dict2 , Dict3,Dict1 作为输出..

标签: ios objective-c sorting nsdictionary keyvaluepair


【解决方案1】:

这与排序无关 - 特别是因为并非数组中的每个字典都参与其中。您要做的是从数组中提取每个字典。

如果您根本没有字典数组,这会简单得多。相反,您应该从一个大字典开始,其中键是数字,值是任何内容(可能是整个字典,也可能是名称本身)。现在您可以将每个数字作为该字典的键查找并获取名称。

{ 1 => A, 2 => B, 3 => C ...}

现在只需抓住objectForKey:@1objectForKey:@4objectForKey:@2,就完成了。

【讨论】:

  • 我从一个 JSON 请求中提取,所以我得到了一个字典数组。所以不幸的是,这对我不起作用。虽然 +1。
  • 我不同意。您可以根据您获得的数据制作我正在描述的字典!您应该这样做,正是为了方便您打算进行的查找。聪明,嗯?
  • 这种为了促进某种查找而重新调整是完全标准的行为。
  • 是的,我同意这是一个聪明的方法。我会看看我能做什么。
【解决方案2】:
for (NSNumber *aNumber in testArray) {
    for (NSDictionary *aDict in anArray) {
        if (aNumber.intValue == [(NSNumber *)[aDict valueForKey:@"Number"]intValue]) {
            [finalArray addObject:aDict];
        }
    }
}

【讨论】:

    【解决方案3】:

    这就是答案。这里我使用了枚举器,速度更快

    NSArray * dicArray = @[@{@"Name": @"B",@"Number":@"2"},
                           @{@"Name": @"A",@"Number":@"1"},
                           @{@"Name": @"D",@"Number":@"4"},
                           @{@"Name": @"C",@"Number":@"3"},
                           @{@"Name": @"E",@"Number":@"5"}];
    NSArray * indArray = @[@(1),@(4),@(2)];
    
    NSMutableArray * resultArray = [NSMutableArray arrayWithCapacity:indArray.count];
    [indArray enumerateObjectsUsingBlock:^(NSNumber* SearchValue, NSUInteger idx, BOOL *stop) {
    
        //search dicArray for object, which match your condition (i.e Number value == obj value)
        NSInteger index = [dicArray indexOfObjectPassingTest:^BOOL(NSDictionary* obj, NSUInteger idx, BOOL *stop) {
            return ([(NSString *)obj[@"Number"] integerValue] == SearchValue.integerValue)? YES : NO;
        }];
    
        resultArray[idx] = dicArray[index];
    }];
    
    NSLog(@"%@",resultArray);
    

    【讨论】:

      【解决方案4】:

      所以我想通了。 基本上我使用了嵌套的 for 循环。

      这里是代码。这可能需要很长时间,具体取决于每个对象的数量。对我来说,每个对象大约有 30 个对象,所以大约需要 50 毫秒:

      NSMutableArray *finalArray = [NSMutableArray array];
      for (NSString *keyName in keyArray) {
          NSString *fname;
          for (NSDictionary *dict in dictArray) {
              fname = [dict objectForKey:@"theKey"];
              if ([fname isEqualToString:keyName])
                  [finalArray addObject:dict];
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-03
        • 2021-12-12
        相关资源
        最近更新 更多