在公共密钥上连接两个对象数组

时间:2013-08-26 03:10:07

标签: objective-c nsmutablearray nsdictionary

我有两个NSMutable Arrays(至少每个5,000条记录),我想加入一个数组/字典。两个数组都有一个共同的key =>值。我想要一个包含两个数组的键/值的单个数组。我在PHP中看到了一些例子(参见Joining two multidimensional arrays using common array value),但我正在寻找Objective C解决方案。

NSMutableArray #1:
{
    [0] => NSObject
    {
        [itemID] => 221
        [Name] => "Adam"
    }
    [1] => NSObject
    {
        [itemID] => 7
        [Name] => "Jacob"
    }
}

NSMutableArray #2:
{
    [0] => NSObject
    {
        [itemID] => 221
        [location] => floor 1
        [room] => 56
    }

    [1] => NSObject
    {
        [itemID] => 7
        [location] => floor 2
        [room] => 12
    }
}

我在寻找:

NSMutableArray
{
    [0] => NSObject
    {
        [itemID] => 221
        [Name] => "Adam"
        [location] => floor 1
        [room] => 56
    }

    [1] => NSObject
    {
        [itemID] => 7
        [Name] => "Jacob" 
        [location] => floor 2
        [room] => 12
    }
}

感谢您的建议:)

1 个答案:

答案 0 :(得分:2)

这不是最有效的,但应该有效......

  NSMutableArray* result = [[NSMutableArray alloc] init];
  for (NSDictionary* dict1 in array1) {
    for (NSDictionary* dict2 in array2) {
      if ([[dict1 objectForKey:@"itemID"] isEqual:
          [dict2 objectForKey:@"itemID"]]) {
             NSMutableDictionary* dict = [dict1 mutableCopy];
             [dict addEntriesFromDictionary:dict2];
             [result addObject: dict];
             break;
          }
    }
  }

更新

以下是一些提高效率的客观C方法......

(1)在比较之前对数组进行排序:

- (NSArray*)sortArray:(NSArray*)array {
    NSArray* sortDescriptors = 
         @[[[NSSortDescriptor alloc] initWithKey:@"itemID" 
                                       ascending:YES]];
    NSArray* result = [array sortedArrayUsingDescriptors:sortDescriptors];
    return result;
}

(2)反向遍历你的词典。然后在得到匹配时删除内部数组的末尾(这是合理的,因为数组已经排序,并且从数组末尾删除对象应该比从开头删除更有效。)

for (NSDictionary* dict1 in [sortedArray1 reverseObjectEnumerator]) {
    for (NSDictionary* dict2 in [sortedArray2 reverseObjectEnumerator]) {
        if ([[dict1 objectForKey:@"itemID"] isEqual:
             [dict2 objectForKey:@"itemID"]]) {
                NSMutableDictionary* dict = [dict1 mutableCopy];
                [dict addEntriesFromDictionary:dict2];
                [result addObject: dict];
                NSUInteger idx = [sortedArray2 indexOfObject:dict2];
                NSRange range= NSMakeRange(idx, sortedArray2.count-1-idx);
                [sortedArray2 removeObjectsInRange:range];
                break;
        }
    }
}

(3)使用基于块的快速枚举:

[sortedArray1 enumerateObjectsWithOptions:NSEnumerationReverse
                               usingBlock:
     ^(NSDictionary* dict1, NSUInteger idx, BOOL *stop) {
         [sortedArray2 enumerateObjectsWithOptions:NSEnumerationReverse
                                        usingBlock:
          ^(NSDictionary* dict2, NSUInteger jdx, BOOL *stop) {
              if ([[dict1 objectForKey:@"itemID"] isEqual:
                   [dict2 objectForKey:@"itemID"]]) {
                      NSMutableDictionary* dict = [dict1 mutableCopy];
                      [dict addEntriesFromDictionary:dict2];
                      [result addObject: dict];
                      NSRange range= NSMakeRange(jdx, sortedArray2.count-1-jdx);
                      [sortedArray2 removeObjectsInRange:range];
                      *stop = YES;
              }
          }];
     }];

在(2)和(3)之间可能存在可忽略不计的计算差异,但(3)具有在每次迭代时传入索引和对象的优点,而在(2)中,您需要使用{获取索引{1}}。

如果您确定每个数组都具有相同的比较键值集,则可以省去indexOfObject并将内部数组缩减简化为:

NSRange

最后 ...

如果您的问题表明,您事先知道您的数据已经排序并且各个数组对象之间存在一对一的对应关系,那么您可以简化:

[sortedArray2 removeLastObject];