I have seen many cases where people sometimes rely on whitespaces which causes some miscalculations.
For Example, take 2 strings;
const str1: string = 'I love stackoverflow'
const str2: string = 'I love stackoverflow'
Using the numOfWhitespaces + 1 thing gives wrong number of words in case of str2. The reason is obvious that it counts 6 number of spaces.
So what should be an easy and better alternative?
The shortest would be using: str1.split(/\s+/).length
But just in case any beginner want to do it with basic loop, here it is:
let str1: string = 'I love stackoverflow'
let numberOfSpaces: number = 0
for (let index = 1; index <= str1.length; index++) {
let lastChar: string = ''
let currentChar: string = ''
currentChar = str1.charAt(index)
lastChar = str1.charAt(index - 1)
if (currentChar === " " && lastChar !== " ") {
numberOfSpaces = numberOfSpaces+ 1
}
else if (currentChar === " " && lastChar === " ") { // This is a test String.
numberOfSpaces = numberOfSpaces + 0
}
//I have not added an else statement for the case if both current char and last char are not whitespaces.
//because I felt there was no need for that and it works perfectly.
}
const finalNumberOfWords: number = numberOfSpaces + 1
console.log(`Number of words final are = ${finalNumberOfWords}`)
So this might look similar to the counting whitespaces method, yes it is but this one doesn't count the extraneous spaces [space followed by a space].
A for loop runs throughout the length of the string. It compares the character at current position of str1[index]and its previous index. If both are whitespaces, it won't count but if previous character was non-null and current is blank, it increments the counter by one.
And finally we add 1 to the counter to display number of words.
Here's a screenshot:
An alternative solution would be to use a regex:
const str2: string = 'I love stackoverflow'
console.log(str2.split(/\s+/).length);
This will ensure that multiple spaces will be splitted.
Test:
console.log('I love stackoverflow'.split(/\s+/).length);
console.log('Ilovestackoverflow'.split(/\s+/).length);
I have the following string:
var strOfCharToSort = "azcdczbdxaaczdbbaazdz"
but I'm trying to get the count of the different substrings
for example:
let countofA = strOfCharToSort.filter { $0 == "a" }.count
and it works but I don't know what substrings are in the string I'm loading
I can sort the string:
strOfCharToSort = String(strOfCharToSort.sorted()) \\ result: aaaaabbbcccddddxzzzzz
But my question to guys there is a way to split the string when if finds a different substring?
I'll really appreciate you help.
let strOfCharToSort = "azcdczbdxaaczdbbaazdz"
let setOfChars = Set(strOfCharToSort)
let setOfCharsArray = Array(setOfChars).sorted()
let listOfSortedCharSubstrings = setOfCharsArray.map { (charachter) in
return strOfCharToSort.filter { $0 == charachter }
}
This is a solution to get the sub strings of a sorted character array.
Try This
let StringOfChar = "azcdczbdxaaczdbbaazdz"
let SetOfAllChar = Set(StringOfChar)
for char in SetOfAllChar {
let countofChar = StringOfChar.filter { $0 == char }.count
print("Count of \(char) : \(countofChar)")
}
Output:
Count of d: 4
Count of z: 5
Count of c: 3
Count of b: 3
Count of a: 5
Count of x: 1
I need to extract numbers from string and put them into a new array in Swift.
var str = "I have to buy 3 apples, 7 bananas, 10eggs"
I tried to loop each characters and I have no idea to compare between Characters and Int.
Swift 3/4
let string = "0kaksd020dk2kfj2123"
if let number = Int(string.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()) {
// Do something with this number
}
You can also make an extension like:
extension Int {
static func parse(from string: String) -> Int? {
return Int(string.components(separatedBy: CharacterSet.decimalDigits.inverted).joined())
}
}
And then later use it like:
if let number = Int.parse(from: "0kaksd020dk2kfj2123") {
// Do something with this number
}
First, we split the string so we can process the single items. Then we use NSCharacterSet to select the numbers only.
import Foundation
let str = "I have to buy 3 apples, 7 bananas, 10eggs"
let strArr = str.split(separator: " ")
for item in strArr {
let part = item.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
if let intVal = Int(part) {
print("this is a number -> \(intVal)")
}
}
Swift 4:
let string = "I have to buy 3 apples, 7 bananas, 10eggs"
let stringArray = string.components(separatedBy: CharacterSet.decimalDigits.inverted)
for item in stringArray {
if let number = Int(item) {
print("number: \(number)")
}
}
Using the "regex helper function" from Swift extract regex matches:
func matchesForRegexInText(regex: String!, text: String!) -> [String] {
let regex = NSRegularExpression(pattern: regex,
options: nil, error: nil)!
let nsString = text as NSString
let results = regex.matchesInString(text,
options: nil, range: NSMakeRange(0, nsString.length))
as! [NSTextCheckingResult]
return map(results) { nsString.substringWithRange($0.range)}
}
you can achieve that easily with
let str = "I have to buy 3 apples, 7 bananas, 10eggs"
let numbersAsStrings = matchesForRegexInText("\\d+", str) // [String]
let numbersAsInts = numbersAsStrings.map { $0.toInt()! } // [Int]
println(numbersAsInts) // [3, 7, 10]
The pattern "\d+" matches one or more decimal digit.
Of course the same can be done without the use of a helper function
if you prefer that for whatever reason:
let str = "I have to buy 3 apples, 7 bananas, 10eggs"
let regex = NSRegularExpression(pattern: "\\d+", options: nil, error: nil)!
let nsString = str as NSString
let results = regex.matchesInString(str, options: nil, range: NSMakeRange(0, nsString.length))
as! [NSTextCheckingResult]
let numbers = map(results) { nsString.substringWithRange($0.range).toInt()! }
println(numbers) // [3, 7, 10]
Alternative solution without regular expressions:
let str = "I have to buy 3 apples, 7 bananas, 10eggs"
let digits = "0123456789"
let numbers = split(str, allowEmptySlices: false) { !contains(digits, $0) }
.map { $0.toInt()! }
println(numbers) // [3, 7, 10]
let str = "Hello 1, World 62"
let intString = str.componentsSeparatedByCharactersInSet(
NSCharacterSet
.decimalDigitCharacterSet()
.invertedSet)
.joinWithSeparator("")
That will get you a string with all the number then you can just do this:
let int = Int(intString)
Just make sure you unwrap it since let int = Int(intString) is an optional.
For me makes more sense to have it as a String extension, probably it's a matter of tastes:
extension String {
func parseToInt() -> Int? {
return Int(self.components(separatedBy: CharacterSet.decimalDigits.inverted).joined())
}
}
So can be used like this:
if let number = "0kaksd020dk2kfj2123".parseToInt() {
// Do something with this number
}
Adapting from #flashadvanced's answer,
I found that the following is shorter and simpler for me.
let str = "I have to buy 3 apples, 7 bananas, 10eggs"
let component = str.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet)
let list = component.filter({ $0 != "" }) // filter out all the empty strings in the component
print(list)
Tried in in the play ground and it works
Hope it helps :)
Swift 2.2
let strArr = str.characters.split{$0 == " "}.map(String.init)
for item in strArr {
let components = item.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet)
let part = components.joinWithSeparator("")
if let intVal = Int(part) {
print("this is a number -> \(intVal)")
}
}
// This will only work with single digit numbers. Works with “10eggs” (no space between number and word
var str = "I have to buy 3 apples, 7 bananas, 10eggs"
var ints: [Int] = []
for char:Character in str {
if let int = "\(char)".toInt(){
ints.append(int)
}
}
The trick here is that you can check if a string is an integer (but you can’t check if a character is).
By looping though every character of the string, use string interpolation to create a string from the character and check if that string cas be casted as a integer.
If it can be, add it to the array.
// This will work with multi digit numbers. Does NOT work with “10 eggs” (has to have a space between number and word)
var str = "I have to buy 3 apples, 7 bananas, 10 eggs"
var ints: [Int] = []
var strArray = split(str) {$0 == " "}
for subString in strArray{
if let int = subString.toInt(){
ints.append(int)
}
}
Here we split the string at any space and create an array of every substring that is in the long string.
We again check every string to see if it is (or can be casted as) an integer.
Thanks for everyone who answered to my question.
I was looking for a block of code which uses only swift grammar, because I'm learning grammar only now..
I got an answer for my question.Maybe it is not an easier way to solve, but it uses only swift language.
var article = "I have to buy 3 apples, 7 bananas, 10 eggs"
var charArray = Array(article)
var unitValue = 0
var total = 0
for char in charArray.reverse() {
if let number = "\(char)".toInt() {
if unitValue==0 {
unitValue = 1
}
else {
unitValue *= 10
}
total += number*unitValue
}
else {
unitValue = 0
}
}
println("I bought \(total) apples.")
Swift 5:
extension String {
var allNumbers: [Int] {
let numbersInString = self.components(separatedBy: .decimalDigits.inverted).filter { !$0.isEmpty }
return numbersInString.compactMap { Int($0) }
}
}
You can get all numbers like
var str = "I have to buy 3 apples, 7 bananas, 10eggs"
// numbers = [3, 7, 10]
numbers = str.allNumbers
That is what i am trying to do:
var i = 0
var string = "abcdef"
for value in string
{
value.[Put value of variable i here] = "a"
i++
}
How can i insert the value of i in the code?
Easiest is probably just convert it to an NSMutableString:
let string = "abcdef".mutableCopy() as NSMutableString
println( "\(string)")
for var i = 0; i < string.length; ++i {
string.replaceCharactersInRange(NSMakeRange(i, 1), withString: "a")
}
println( "\(string)")
Yes, it's a bit ugly but it works.
A much cleaner way is to use Swifts map function:
var string = "abcdef"
let result = map(string) { (c) -> Character in
"a"
}
println("\(result)") // aaaaaa
You should just be able to use the following but this doesn't compile:
map(string) { "a" }
In you comments you mention you want to split up the string on a space, you can just use this for that:
let stringWithSpace = "abcdef 012345"
let splitString = stringWithSpace.componentsSeparatedByString(" ")
println("\(splitString[0])") // abcdef
println("\(splitString[1])") // 012345
Hey guys I have string "69 - 13" How to detect "-" in the string and how to sum the numbers in the string 69+13=82 ?
There are various method to do that (componentsSeparatedByString, NSScanner, ...).
Here is one using only Swift library functions:
let str = "69 - 13"
// split string into components:
let comps = split(str, { $0 == "-" || $0 == " " }, maxSplit: Int.max, allowEmptySlices: false)
// convert strings to numbers (use zero if the conversion fails):
let nums = map(comps) { $0.toInt() ?? 0 }
// compute the sum:
let sum = reduce(nums, 0) { $0 + $1 }
println(sum)
Here is an updated implementation in Swift 4 that relies on higher order functions to perform the operation:
let string = "69+13"
let number = string.components(separatedBy: CharacterSet.decimalDigits.inverted)
.compactMap({ Int($0) })
.reduce(0, +)
print(number) // 82
The components(separatedBy: CharacterSet.decimalDigits.inverted) removes all non-digit values and creates an array for each group of values (in this case 69 and 13)
Int($0) converts your string value into an Int
compactMap gets rid of any nil values, ensuring that only valid values are left
reduce then sums up the values that remain in your array