0

我有两个 NSMutable 数组(每个至少 5,000 条记录),我想加入一个数组/字典。两个数组都有一个共同的 key=>value。我想要一个包含两个数组的键/值的数组。我在 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
    }
}

谢谢你的建议:)

4

1 回答 1

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) 中,您需要使用indexOfObject.

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

[sortedArray2 removeLastObject];

终于……

如果正如您的问题所暗示的那样,您事先知道您的数据已排序并且各个数组对象之间存在一对一的对应关系,则可以简化:

[arrayA enumerateObjectsUsingBlock:
    ^(NSDictionary* dict, NSUInteger idx, BOOL *stop) {
        NSMutableDictionary* mutableDict = [dict mutableCopy];
        [mutableDict addEntriesFromDictionary:arrayB[idx]];
         [result addObject:mutableDict];
    }];
于 2013-08-26T04:02:28.323 回答