1

My main string is like this "90000+8000-1000*10". I wanted to find the length of substring that contain number and make it into array. So it will be like this:

print(substringLength[0]) //Show 5
print(substringLength[1]) //Show 4

Could anyone help me with this? Thanks in advance!

Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
Firda Sahidi
  • 1,227
  • 1
  • 11
  • 22

5 Answers5

3

⚠️ Be aware of using replacingOccurrences!

Although this method (mentioned by @Raja Kishan) may work in some cases, it's not forward compatible and will fail if you have unhandled characters (like other expression operators)


✅ Just write it as you say it:

let numbers = "90000+8000-1000*10".split { !$0.isWholeNumber && $0 != "." }

You have the numbers! go ahead and count the length

numbers[0].count // show 5
numbers[1].count // shows 4

You can also have the operators like:

let operators = "90000+8000-1000*10".split { $0.isWholeNumber || $0 == "." }
Mojtaba Hosseini
  • 95,414
  • 31
  • 268
  • 278
1

You can split when the character is not a number.

The 'max splits' method is used for performance, so you don't unnecessarily split part of the input you don't need. There are also preconditions to handle any bad input.

func substringLength(of input: String, at index: Int) -> Int {
    precondition(index >= 0, "Index is negative")
    let sections = input.split(maxSplits: index + 1, omittingEmptySubsequences: false) { char in
        !char.isNumber
    }
    precondition(index < sections.count, "Out of range")
    return sections[index].count
}
let str = "90000+8000-1000*10"

substringLength(of: str, at: 0) // 5
substringLength(of: str, at: 1) // 4
substringLength(of: str, at: 2) // 4
substringLength(of: str, at: 3) // 2
substringLength(of: str, at: 4) // Precondition failed: Out of range
George
  • 25,988
  • 10
  • 79
  • 133
0

If the sign (operator) is fixed then you can replace all signs with a common one sign and split the string by a common sign.

Here is the example

extension String {
    func getSubStrings() -> [String] {
        let commonSignStr = self.replacingOccurrences(of: "+", with: "-").replacingOccurrences(of: "*", with: "-")
        return commonSignStr.components(separatedBy: "-")
    }
}
let str = "90000+8000-1000*10"
str.getSubStrings().forEach({print($0.count)})
Raja Kishan
  • 16,767
  • 2
  • 26
  • 52
  • Try not to extend the general types (like String) for specific use cases. Or at least make it more conventional by asking for characters. – Mojtaba Hosseini Aug 27 '21 at 16:23
  • Why ? Split property also declared in string – Raja Kishan Aug 27 '21 at 16:32
  • I mean something like: `extension String { func getSubStrings(separatedBy separators: [String]) -> [String] { var mutatedSelf = self for separator in separators { mutatedSelf = mutatedSelf.replacingOccurrences(of: separator, with: "-") } return mutatedSelf.components(separatedBy: "-") } }` – Mojtaba Hosseini Aug 27 '21 at 16:42
  • You are not returning substrings. To return substrings you would need to use the split method. Note that components(separatedBy:) method would also return empty strings if you have a string that ends with an operator or have two operators in a row ("+-", "--", "++" or "--"). – Leo Dabus Aug 27 '21 at 17:16
0

I'd assume that the separators are not numbers, regardless of what they are.

let str = "90000+8000-1000*10"
let arr = str.split { !$0.isNumber }
let substringLength = arr.map { $0.count }

print(substringLength) // [5, 4, 4, 2]
print(substringLength[0]) //Show 5
print(substringLength[1]) //Show 4
Ahmad F
  • 30,560
  • 17
  • 97
  • 143
0

Don't use isNumber Character property. This would allow fraction characters as well as many others that are not single digits 0...9.

Discussion
For example, the following characters all represent numbers:
“7” (U+0037 DIGIT SEVEN)
“⅚” (U+215A VULGAR FRACTION FIVE SIXTHS)
“㊈” (U+3288 CIRCLED IDEOGRAPH NINE)
“” (U+1D7E0 MATHEMATICAL DOUBLE-STRUCK DIGIT EIGHT)
“๒” (U+0E52 THAI DIGIT TWO)

let numbers = "90000+8000-1000*10".split { !("0"..."9" ~= $0) }   // ["90000", "8000", "1000", "10"]

let numbers2 = "90000+8000-1000*10 ५ ๙ 万 ⅚  ๒ ".split { !("0"..."9" ~= $0) }   // ["90000", "8000", "1000", "10"]
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571