如何添加所有的十进制数的一个NSMutableArray(How to add all decima

2019-07-21 11:21发布

我有一个NSMutableArray其中有一些NSDecimalNumber在里面,像(500,50.80,70,8000)

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

我试着使用

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

但是失败了。

Answer 1:

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

看看NSDecimalNumber类参考

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


Answer 2:

一个简单的方法来添加所有NSNumber S IN的阵列(类似于@Mahonor在注释中说的):

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

相反的是,在收集运营商:和美国,数字数组中被转换为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 )。

人们还可以看到, decimalValue从所谓

-[NSArray(NSKeyValueCoding) _sumForKeyPath:]

和用于该方法的汇编代码显示NSDecimalAdd是使用添加的号码。



Answer 3:

马诺哈尔的在评论中建议也不错。 事实上,你可以使用KVC收集运营商做一个班轮出这一点: [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是一个结构,而不是一个对象; 它不应该被声明为指针,如果不是这样,你就不能添加。 这不是一个解决方案正确的路线。



文章来源: How to add all decimal numbers in an NSMutableArray