如何在NSMutableArray中添加所有十进制数

时间:2013-03-13 06:42:10

标签: objective-c nsarray nsdecimalnumber

我有一个NSMutableArray,其中有一些NSDecimalNumber,例如(500,50.80,70,8000)

现在我想将所有decimal numbers加在一起。

我试过用

for (NSDecimalNumber *number in self.numbersArray)
{
    NSDecimal *sum += [number decimalValue]
}

但失败了。

3 个答案:

答案 0 :(得分:5)

在数组中添加所有NSNumber的简单方法是(类似于@Mahonor在评论中所说的):

NSArray *myArray = ... // array of NSNumber (or NSDecimalNumber) objects
NSNumber *sum = [myArray valueForKeyPath:@"@sum.self"];

Collection Operators: sum状态相反,数组中的数字转换为double,而是NSDecimal。因此,添加十进制数时, 没有精度丢失 。即使是非十进制数的NSNumber个对象也会转换为NSDecimal以进行添加。求和的结果是NSDecimalValue的实例。

我以两种不同的方式验证(或尝试过)。首先,我运行了这段代码

NSNumber *a = [NSNumber numberWithDouble:1.2];
NSNumber *b = [NSDecimalNumber decimalNumberWithString:@"-5.7"];
NSArray *myArray = @[a, b];
id sum = [myArray valueForKeyPath:@"@sum.self"];

并通过设置环境变量“NSObjCMessageLoggingEnabled = YES”激活Objective-C消息日志记录。从创建的“/ tmp / msgSends-NNNN”文件中可以看出,decimalNumber(而不是doubleValue)被发送到两个数字对象。

其次,我创建了一个实现decimalValuedoubleValue的自定义类,并将@sum.self应用于自定义类的对象数组:

@interface MyClass : NSObject
@property (nonatomic, assign) double value;
@end

@implementation MyClass

- (NSDecimal)decimalValue
{
    return [[NSNumber numberWithDouble:self.value] decimalValue];
}

- (double)doubleValue
{
    return self.value;
}

@end

MyClass *a = [MyClass new]; a.value = 1.2;
MyClass *b = [MyClass new]; b.value = -5.7;
NSArray *myArray = @[a, b];
id sum = [myArray valueForKeyPath:@"@sum.self"];

通过在两种方法中设置断点,可以看出只有decimalValue用于求和(如果类没有实现valueForKeyPath:@"@sum.self"decimalValue会抛出异常。)

还可以看到从{/ p>调用decimalValue

-[NSArray(NSKeyValueCoding) _sumForKeyPath:]

并且此方法的汇编程序代码显示NSDecimalAdd用于添加数字。

答案 1 :(得分:3)

使用- (NSDecimalNumber *)decimalNumberByAdding:(NSDecimalNumber *)decimalNumber

查看NSDecimalNumber Class Reference

NSDecimalNumber *lNumber = [NSDecimalNumber zero];
for (NSDecimalNumber *number in self.numbersArray)
{
    lNumber = [lNumber decimalNumberByAdding:number];
}

答案 2 :(得分:1)

Manohar在评论中提出的建议并不错。您确实可以使用KVC collection operators制作一行内容:[myArray valueForKeyPath:@"@sum.doubleValue"];,但您可能会失去精确度(取决于您存储的数字)。

你基本上在寻找“减少”功能;您需要将调用链接到decimalNumberByAdding:,以便每个调用都将数组的后续元素作为其参数。使用NSArray

performSelector:withObject:上执行此操作非常简单
@implementation NSArray (Reduce)
- (id)reduceUsingSelector: (SEL)sel
{
    id res = [self objectAtIndex:0];
    for( id obj in [self subarrayWithRange:(NSRange){1, [self count]-1}] ){
        res = [res performSelector:sel withObject:obj];
    }

    return res;
}
@end

像这样使用:NSDecimalNumber * sum = [myArray reduceUsingSelector:@selector(decimalNumberByAdding:)];

您拥有的代码不成功,因为NSDecimal是结构,而不是对象;它不应该被声明为指针,如果不是,你将无法添加它。这不是解决方案的正确途径。