【问题标题】:Perform arithmetic on two NSArray's in component wise fashion?以组件方式对两个 NSArray 执行算术运算?
【发布时间】:2012-01-27 14:55:06
【问题描述】:

我有两个 NSArray 对象,我想以组件方式将这两个数组添加在一起,以便将数组 1 中索引 i 处的 int 添加到数组 2 中索引 i 处的 int 中,并将结果添加到新数组中.有没有比 for (int i=0; i

    NSArray *array1 = [NSArray arrayWithObjects:
                   [NSNumber numberWithInt:1],
                   [NSNumber numberWithInt:2],
                   [NSNumber numberWithInt:3],
                   [NSNumber numberWithInt:4],
                   nil];

NSArray *array2 = [NSArray arrayWithObjects:
                   [NSNumber numberWithInt:10],
                   [NSNumber numberWithInt:20],
                   [NSNumber numberWithInt:30],
                   [NSNumber numberWithInt:40],
                   nil];

NSMutableArray *resultArray = [[NSMutableArray alloc] initWithCapacity:[array1 count]];

for (int i=0; i<[array1 count]; i++) {
    int result = [[array1 objectAtIndex:i] intValue] + [[array2 objectAtIndex:i] intValue];
    [resultArray addObject:[NSNumber numberWithInt:result]];                                
} 

谢谢,感谢任何 cmets。

【问题讨论】:

    标签: iphone objective-c arrays


    【解决方案1】:

    这里有一个使用块和并发枚举的例子:

    NSArray *array1 = [NSArray arrayWithObjects:
                       [NSNumber numberWithInt:1],
                       [NSNumber numberWithInt:2],
                       [NSNumber numberWithInt:3],
                       [NSNumber numberWithInt:4],
                       nil];
    
    NSArray *array2 = [NSArray arrayWithObjects:
                       [NSNumber numberWithInt:10],
                       [NSNumber numberWithInt:20],
                       [NSNumber numberWithInt:30],
                       [NSNumber numberWithInt:40],
                       nil];
    
    NSMutableArray *resultArray = [[NSMutableArray alloc] initWithCapacity:[array1 count]];
    for (int i=0; i<[array1 count]; i++) {
        [resultArray addObject:[NSNull null]];
    }
    
    dispatch_queue_t resultArrayQueue = dispatch_queue_create("com.yourcompany.appname.resultsArrayQueue", DISPATCH_QUEUE_SERIAL);
    
    [array1 enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        int num1 = [(NSNumber *)obj intValue];
        int num2 = [[array2 objectAtIndex:idx] intValue];
        NSNumber *result = [NSNumber numberWithInt:(num1 + num2)];
        dispatch_async(resultArrayQueue, ^{
            [resultArray replaceObjectAtIndex:idx withObject:result];
        });
    }];
    
    NSLog(@"Result array: %@", resultArray);
    

    它是否更快需要分析来确定。我的预感是它并没有快多少,甚至可能会因为 GCD 调度的开销(相对较小,但仍然存在)而变慢。但是,对于比简单加法更复杂的计算,这让您了解如何使用并发枚举以多核感知的方式轻松地对数组中的每个元素执行操作。

    如果您在顶级数组中有 x 个数组(如您的评论中所述),则可以将 -enumerateObjectsWithOptions:usingBlock: 调用替换为以下内容:

    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_apply(numberOfItemsInEachArray, globalQueue, ^(size_t idx) {
        NSInteger sum = 0;
        for (NSArray *array in parentArray) {
            sum += [[array objectAtIndex:idx] integerValue];
        }
    
        NSNumber *result = [NSNumber numberWithInteger:sum];
        dispatch_async(resultArrayQueue, ^{
            [resultArray replaceObjectAtIndex:idx withObject:result];
        });
    });
    

    dispatch_apply() 是一个 Grand Central Dispatch 函数,它只是简单地运行一段代码指定的次数。由于我们告诉它使用我们通过dispatch_get_global_queue() 获得的全局并发队列,它可以同时运行块的不同调用,从而在多核机器上提供(可能的)性能优势。与大多数编程问题一样,还有很多其他方法可以解决这个问题。这只是我想到的一个。

    【讨论】:

    • 我想更多的是,如果我有 x 个数组相加在一起,比如从一个数组数组中,x 个数组可以根据用户输入而改变,我将如何做到这一点。有什么想法吗?
    • 同样的基本方法应该可以工作。在枚举块中,不是简单地将 array1 中的值与 array2 中的相应值相加,而是遍历顶级父数组中的所有数组,从每个数组中获取当前索引的值,然后将所有值相加将它们放在结果数组中。如果您需要查看此代码,请告诉我。
    • 如果您不介意为此提供代码,我将不胜感激。我只是在学习如何编程,一切对我来说都是新的。谢谢
    • 好的,我添加了另一个代码sn-p。请注意, numberOfItemsInEachArray 必须使用每个子数组中的项目数进行初始化,并且它们都必须具有相同数量的项目,否则您将崩溃。可以修改代码以相当容易地处理不同长度的数组。
    【解决方案2】:

    如果你想总结它们,你真的无法避免至少检查一次这两个数组。但是,您可以将数组视为矩阵。在这种情况下,有一些非常快速的矩阵算术算法或库供您使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-06
      • 2017-01-10
      • 2013-06-29
      • 1970-01-01
      • 2012-06-19
      相关资源
      最近更新 更多