我有一个NSMutableArray
,其中有一些NSDecimalNumber
,例如(500,50.80,70,8000)
现在我想将所有decimal numbers
加在一起。
我试过用
for (NSDecimalNumber *number in self.numbersArray)
{
NSDecimal *sum += [number decimalValue]
}
但失败了。
答案 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
)被发送到两个数字对象。
其次,我创建了一个实现decimalValue
和doubleValue
的自定义类,并将@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
是结构,而不是对象;它不应该被声明为指针,如果不是,你将无法添加它。这不是解决方案的正确途径。