Swift randomizer with variables - swift

I have two String Type values as Int number.
I like to randomize between these two.
With this code:
let random = Int.random(in: myvar1...myvar2)
it does not work. How can i fix it?

I assume your variables look like this?
let myvar1: String = "1"
let myvar2: String = "10"
Those are both Strings, so myvar1...myvar2 becomes a range of String.
However, the random(in:) method takes in a range of Int, so you'll first need to convert them to Ints.
if let myvar1Int = Int(myvar1), let myvar2Int = Int(myvar2) {
let random = Int.random(in: myvar1Int...myvar2Int)
print(random) /// Result: 6
}

Related

character extract from string in swift

I have a task to do something with a chess board. The input gives us a starting position of some chess figure. For example "b4" or "a6" or something like that. How can i decompose the input and make from it two integer numbers, like in C++:
string input;
cin>>input
int coord_x = input[0] - 'a';
int coord_y = input[1]
I cannot manage to do that in swift. I do something like:
let input : String=readLine()!
let characters = Array(input)
and then try to take the int but it doesnt work, no matter what i try...
and what type is the content of the Array in swift?
You can retrieve the c string representation like this:
let string = "a5"
let scalars = string.lowercased().cString(using: .ascii)!
let first = scalars[0]
let second = scalars[1]
It could be safer to retrieve the unicodeScalar characters instead:
let string = "a5".lowercased()
let characters = Array(string.unicodeScalars)
let first = characters[0].value - UnicodeScalar(unicodeScalarLiteral: "a").value

How to filter characters from a string in Swift 4

In the following Swift 3 code I'm extracting all numbers from a string but I can not figure out how to do the same thing in Swift 4.
var myString = "ABC26FS464"
let myNumbers = String(myString.characters.filter { "01234567890".characters.contains($0)})
print(myNumbers) // outputs 26464
How can I extract all numbers from a string in Swift 4?
Swift 4 makes it a little simpler. Just remove the .characters and use
let myNumbers = myString.filter { "0123456789".contains($0) }
But to really do it properly, you might use the decimalDigits character set...
let digitSet = CharacterSet.decimalDigits
let myNumbers = String(myString.unicodeScalars.filter { digitSet.contains($0) })
Easiest:
As "Character" has almost all the most used character checking with ".isXY" computed properties, you can use this pattern, which seems to be the most convenient and Swifty way to do string filtering.
/// Line by line explanation.
let str = "Stri1ng wi2th 3numb4ers".filter(\.isNumber) // "1234"
let int = Int(str) // Optional<Int>(1234)
let unwrappedInt = int! // 1234
/// Solution.
extension String {
/// Numbers in the string as Int.
///
/// If doesn't have any numbers, then 0.
var numbers: Int {
Int(filter(\.isNumber)) ?? 0
}
/// Numbers in the string as Int.
///
/// If doesn't have any numbers, then nil.
var optionalNumbers: Int? {
Int(filter(\.isNumber))
}
}

Why does swift substring with range require a special type of Range

Consider this function to build a string of random characters:
func makeToken(length: Int) -> String {
let chars: String = "abcdefghijklmnopqrstuvwxyz0123456789!?##$%ABCDEFGHIJKLMNOPQRSTUVWXYZ"
var result: String = ""
for _ in 0..<length {
let idx = Int(arc4random_uniform(UInt32(chars.characters.count)))
let idxEnd = idx + 1
let range: Range = idx..<idxEnd
let char = chars.substring(with: range)
result += char
}
return result
}
This throws an error on the substring method:
Cannot convert value of type 'Range<Int>' to expected argument
type 'Range<String.Index>' (aka 'Range<String.CharacterView.Index>')
I'm confused why I can't simply provide a Range with 2 integers, and why it's making me go the roundabout way of making a Range<String.Index>.
So I have to change the Range creation to this very over-complicated way:
let idx = Int(arc4random_uniform(UInt32(chars.characters.count)))
let start = chars.index(chars.startIndex, offsetBy: idx)
let end = chars.index(chars.startIndex, offsetBy: idx + 1)
let range: Range = start..<end
Why isn't it good enough for Swift for me to simply create a range with 2 integers and the half-open range operator? (..<)
Quite the contrast to "swift", in javascript I can simply do chars.substr(idx, 1)
I suggest converting your String to [Character] so that you can index it easily with Int:
func makeToken(length: Int) -> String {
let chars = Array("abcdefghijklmnopqrstuvwxyz0123456789!?##$%ABCDEFGHIJKLMNOPQRSTUVWXYZ".characters)
var result = ""
for _ in 0..<length {
let idx = Int(arc4random_uniform(UInt32(chars.count)))
result += String(chars[idx])
}
return result
}
Swift takes great care to provide a fully Unicode-compliant, type-safe, String abstraction.
Indexing a given Character, in an arbitrary Unicode string, is far from a trivial task. Each Character is a sequence of one or more Unicode scalars that (when combined) produce a single human-readable character. In particular, hiding all this complexity behind a simple Int based indexing scheme might result in the wrong performance mental model for programmers.
Having said that, you can always convert your string to a Array<Character> once for easy (and fast!) indexing. For instance:
let chars: String = "abcdefghijklmnop"
var charsArray = Array(chars.characters)
...
let resultingString = String(charsArray)

String convert to Int and replace comma to Plus sign

Using Swift, I'm trying to take a list of numbers input in a text view in an app and create a sum of this list by extracting each number for a grade calculator. Also the amount of values put in by the user changes each time. An example is shown below:
String of: 98,99,97,96...
Trying to get: 98+99+97+96...
Please Help!
Thanks
Use components(separatedBy:) to break up the comma-separated string.
Use trimmingCharacters(in:) to remove spaces before and after each element
Use Int() to convert each element into an integer.
Use compactMap (previously called flatMap) to remove any items that couldn't be converted to Int.
Use reduce to sum up the array of Int.
let input = " 98 ,99 , 97, 96 "
let values = input.components(separatedBy: ",").compactMap { Int($0.trimmingCharacters(in: .whitespaces)) }
let sum = values.reduce(0, +)
print(sum) // 390
For Swift 3 and Swift 4.
Simple way: Hard coded. Only useful if you know the exact amount of integers coming up, wanting to get calculated and printed/used further on.
let string98: String = "98"
let string99: String = "99"
let string100: String = "100"
let string101: String = "101"
let int98: Int = Int(string98)!
let int99: Int = Int(string99)!
let int100: Int = Int(string100)!
let int101: Int = Int(string101)!
// optional chaining (if or guard) instead of "!" recommended. therefore option b is better
let finalInt: Int = int98 + int99 + int100 + int101
print(finalInt) // prints Optional(398) (optional)
Fancy way as a function: Generic way. Here you can put as many strings in as you need in the end. You could, for example, gather all the strings first and then use the array to have them calculated.
func getCalculatedIntegerFrom(strings: [String]) -> Int {
var result = Int()
for element in strings {
guard let int = Int(element) else {
break // or return nil
// break instead of return, returns Integer of all
// the values it was able to turn into Integer
// so even if there is a String f.e. "123S", it would
// still return an Integer instead of nil
// if you want to use return, you have to set "-> Int?" as optional
}
result = result + int
}
return result
}
let arrayOfStrings = ["98", "99", "100", "101"]
let result = getCalculatedIntegerFrom(strings: arrayOfStrings)
print(result) // prints 398 (non-optional)
let myString = "556"
let myInt = Int(myString)

How to convert string to UInt32?

I am a beginner in swift and I am having a problem with convering string to UInt32.
let Generator = (ReadableJSON ["People"] [Person]["F1"].string! as NSString).doubleValue
if Generator == 1 {
NameLabel1 = ReadableJSON ["People"] [Person]["A1"].string as String!
NameImeNaObekt = ReadableJSON ["People"] [Person] ["B1"].string as String!
Picture = ReadableJSON ["People"] [Person] ["E1"].string as String!
} else {
let RGen = arc4random_uniform ("\(Generator)") // here is the error
}
Would you advise me how to fix it. The problem is in the last line, which is red and it says Cannot convert value of type String to UInt32.
The main idea is that I am reading the number from a JSON file and I have to populate this number into the arc4random_uniform.
arc4random_uniform(UInt32)
accept an UInt32 value but you are passing an String value to it
this converts your number to string
"\(Generator)"
the last line should be like this
let RGen = arc4random_uniform (UInt32(Generator))
and if you want to 'RGen' is an String you can do it this way
"\(RGen)"
String(RGen)
var RGen= 0
let RGen =int( arc4random_uniform ("\(Generator)") )
or
let RGen =( arc4random_uniform ("(Generator)") ).toInt
Look here