0

Reading through this problem in a book

Given a string that contains both letters and numbers, write a function that pulls out all the numbers then returns their sum. Sample input and output

The string “a1b2c3” should return 6 (1 + 2 + 3). The string “a10b20c30” should return 60 (10 + 20 + 30). The string “h8ers” should return “8”.

My solution so far is

import Foundation

func sumOfNumbers(in string: String) -> Int {
    var numbers = string.filter { $0.isNumber }
    var numbersArray = [Int]()

    for number in numbers {
        numbersArray.append(Int(number)!)
    }

    return numbersArray.reduce(0, { $0 * $1 }) 
}

However, I get the error

Solution.swift:8:33: error: cannot convert value of type 'String.Element' (aka 'Character') to expected argument type 'String'
        numbersArray.append(Int(number)!)
                                ^

And I'm struggling to get this number of type String.Element into a Character. Any guidance would be appreciated.

Jakory
  • 23
  • 4
  • Unrelated, but how `{ $0 * $1 }` works for an addition? "I'm struggling to get this number of type String.Element into a Character": `String.Element` IS a `Character`, your issue is that there is a `init(_ string:)`, but not `init(_ charcater:)` method. You could use `String(number)`, so `Int(String(number))`. But you'll still have the flaw of considering "10" as "1" and "0". – Larme Apr 04 '22 at 15:18
  • You could see https://stackoverflow.com/questions/30342744/swift-how-to-get-integer-from-string-and-convert-it-into-integer for how to extract numbers – Larme Apr 04 '22 at 15:23
  • @Larme silly mistake from me, misread the problem while tired as asking to multiply the numbers. – Jakory Apr 04 '22 at 15:58

1 Answers1

1

The error occurs because Int.init is expecting a String, but the argument number you gave is of type Character.

It is easy to fix the compiler error just by converting the Character to String by doing:

numbersArray.append(Int("\(number)")!)

or just:

numbersArray.append(number.wholeNumberValue!)

However, this does not produce the expected output. First, you are multiplying the numbers together, not adding. Second, you are considering each character separately, and not considering groups of digits as one number.

You can instead implement the function like this:

func sumOfNumbers(in string: String) -> Int {
    string.components(separatedBy: CharacterSet(charactersIn: "0"..."9").inverted)
        .compactMap(Int.init)
        .reduce(0, +)
}

The key thing is to split the string using "non-digits", so that "10" and "20" etc gets treated as individual numbers.

Sweeper
  • 213,210
  • 22
  • 193
  • 313