Lester
Lester

Reputation: 731

How to sum NSNumber array in Swift?

How to sum NSNumber array in Swift? I'm getting this error when I use .reduce. any other way to sum the NSNumber array?

Cannot invoke 'reduce' with an argument list of type '(Int, _)

var record = [Record]()
var incomeFilter: [Record] = []

let formatter = NumberFormatter()
formatter.numberStyle = .currencyAccounting
formatter.currencySymbol = "¥"
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2

incomeFilter = record.filter { $0.recordtype!.contains("Income") && $0.createdAt! == recordItem.createdAt!}
let incomeSumArray = incomeFilter.map{formatter.number(from: $0.amount!) ?? 0.00}.reduce(0, +)
//Cannot invoke 'reduce' with an argument list of type '(Int, _)
print(incomeSumArray)

//result without .reduce
//[9.99, 6.58, 7777.77] 

Upvotes: 0

Views: 1194

Answers (2)

Ahmad F
Ahmad F

Reputation: 31645

You could map the incomeFilter to be an array of doubles (incomeFilter.map{formatter.number(from: $0.amount!) ?? 0.00}) before reducing it:

let incomeSumArray = incomeFilter.map {
        formatter.number(from: $0.amount!) ?? 0.00
    }.map {
        $0.doubleValue
    }.reduce(0, +)

Upvotes: 0

Sulthan
Sulthan

Reputation: 130102

I think the problem is using ?? 0 with an optional of type NSNumber. You always need the same type when nil-coalescing. You have to convert NSNumber to a numeric value (double) first:

let incomeSum = incomeFilter
    .map {
        formatter.number(from: $0.amount!)?.doubleValue ?? 0
     }
    .reduce(0, +)

or

let incomeSum = incomeFilter
    .map {
        guard
           let amountString = $0.amount,
           let number = formatter.number(from: amountString)
        else {
           return 0
        }

        return number.doubleValue
     }
    .reduce(0, +)  

Upvotes: 3

Related Questions