Apply a number to each letter in text swift2
You could use the unicode scalar representation of each character (look up ASCII tables) and sum these shifted by -96
(such that a -> 1
, b -> 2
and so on). In the following, upper case letters will generate the same number value as lower case ones.
let foo = "cae"
let pattern = UnicodeScalar("a")..."z"
let charsAsNumbers = foo.lowercaseString.unicodeScalars
.filter { pattern ~= $0 }
let sumOfNumbers = charsAsNumbers
.reduce(0) { $0 + $1.value - 96 }
print(sumOfNumbers) // 9
Or, to simplify usage, create a function or String
extension
/* as a function */
func getNumberSum(foo: String) -> UInt32 {
let pattern = UnicodeScalar("a")..."z"
return foo.lowercaseString.unicodeScalars
.filter { pattern ~= $0 }
.reduce(0) { $0 + $1.value - 96 }
}
/* or an extension */
extension String {
var numberSum: UInt32 {
let pattern = UnicodeScalar("a")..."z"
return self.lowercaseString.unicodeScalars
.filter { pattern ~= $0 }
.reduce(0) { $0 + $1.value - 96 }
}
}
Example usage for your case:
/* example test case (using extension) */
let textField1 = UITextField()
let textField2 = UITextField()
textField1.text = "cAe"
textField2.text = "FCa"
/* example usage */
if let textFieldText1 = textField1.text,
let textFieldText2 = textField2.text {
print(textFieldText1.numberSum) // 9
print(textFieldText2.numberSum) // 10
print(textFieldText1.numberSum
== textFieldText2.numberSum) // false
}
Iterate through alphabet in Swift explanation
Why does it work?
This works “by chance” because the integer is stored in little-endian byte order.
The integer 97
is stored in memory as 8 bytes
0x61 0x00 0x00 0x00 0x00 0x00 0x00 0x00
and in write(1, &alpha, 1)
, the address of that memory location is
passed to the write
system call. Since the last parameter (nbyte
)
is 1, the first byte at that memory address is written to the
standard output: That is 0x61
or 97
, the ASCII code of the lettera
.
In Swift though, I couldn't assign an integer to Character or String type variable.
The Swift equivalent of char
is CChar
, a type alias for Int8
:
var alpha: CChar = 97
Here is a solution which does not rely on the memory layout and
works for non-ASCII character as well:
let first: UnicodeScalar = "α"
let last: UnicodeScalar = "ω"
for v in first.value...last.value {
if let c = UnicodeScalar(v) {
print(c, terminator: "")
}
}
print()
// αβγδεζηθικλμνξοπρςστυφχψω
How to assign each letter in a textfield to a number in Xcode
Easiest solution that comes to my mind, but it will only work as long as you assign incremental values based on the order of the alphabet letters.
// Make every letter uppercase to compare on the same scale of unicode values
NSString * str = [yourTextField.text uppercaseString];
NSUInteger total = 0;
for (int i = 0 ; i < str.length ; ++i ) {
// 'A' unicode value is 65, so by substracting 64 you'll get 1 for A, 2 for B, 3 for C...
total += [str characterAtIndex:i] - 64;
}
NSLog(@"Total is %d", total);
You should still make sure you don't get any symbols or so, but this will sum up all the letters in your string.
Swift: Convert index to int
Leo Dabus has a nice extension for this in this post
extension String {
var letterValue: Int {
return Array("abcdefghijklmnopqrstuvwxyz".characters).indexOf(Character(lowercaseString)) ?? 0
}
var wordValue: Int {
// I prefer to use reduce
return characters.reduce(0) { $0 + String($1).letterValue }
}
}
let name1 = "myname"
print(name1.wordValue) // 65
Make UITextField accept small alphabet letter only in Swift?
You can use regular expression for it, in example below regular expression that allows only small symbols
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if string.isEmpty {
return true
}
let regex = "[a-z]{1,}"
return NSPredicate(format: "SELF MATCHES %@", regex).evaluate(with: string)
}
Swift: Generate a set of (X) random 6 character substrings
Thanks to @vacawama here's a possible solution.
1. Create the alphabet
let alphabet = Array("ABCDEFGHIJKLMNOPQRSTUVWXYZ".characters)
2. Create the 6 "sequences"
let sequences = (0..<5).map { _ -> String in
let startIndex = Int(arc4random_uniform(UInt32(alphabet.count - 5)))
let endIndex = startIndex + 5
return String(alphabet[startIndex...endIndex])
}
["PQRSTU", "DEFGHI", "JKLMNO", "CDEFGH", "KLMNOP"]
3. Get the last char for each sequence
let lastChars = sequences.flatMap { $0.characters.last }
["U", "I", "O", "H", "P"]
4. Build 5 elms
Here's the code snippet
let elms = lastChars.map { char0 -> String in
var tempAlphabet = alphabet
tempAlphabet.removeAtIndex(tempAlphabet.indexOf(char0)!)
let index1 = Int(arc4random_uniform(UInt32(tempAlphabet.count)))
let char1 = tempAlphabet.removeAtIndex(index1)
let index2 = Int(arc4random_uniform(UInt32(tempAlphabet.count)))
let char2 = tempAlphabet[index2]
return String(Array(Set<Character>([char0, char1, char2])))
}
["DUN", "ZIQ", "ROP", "HSW", "PGS"]
Update
Here's another solution to fix the problem hightligted by @dfri in the comments below. The following code snipped could replace the previous bullet 4.
extension Array {
mutating func removeRandom() -> Element {
let index = Int(arc4random_uniform(UInt32(count)))
return removeAtIndex(index)
}
}
var availableChars = Array(Set(alphabet).subtract(lastChars))
let elms = lastChars.map { String([$0, availableChars.removeRandom(), availableChars.removeRandom()]) }
How to capitalize every other letter in a string/array in Swift?
You can combine enumerated
, map
, and joined
in sequence to create the result:
let str = "This is a test"
let result = str.enumerated()
.map { $0.offset % 2 == 0 ? String($0.element).uppercased() : String($0.element) }
.joined()
print(result)
ThIs iS A TeSt
Explanation:
- A
String
can be enumerated as if it were an array ofCharacter
. Calling.enumerated()
on aString
causes it to produces a sequence of(offset: Int, element: Character)
tuples. map
takes a sequence and creates an array. The closure followingmap
is called for each element of the sequence in turn and the value that the closure returns becomes the next element in the new array.$0
is the default name for the value passed to map. In this case, we're passing the(offset: Int, element: Character)
tuple.$0.offset
is the position of the character in theString
, and$0.element
is the character.- The ternary operator is used here to return the
uppercased()
String
that is created from theCharacter
if the offset is even or just theString
if the offset is odd. - The result of the
map
is[String]
, andjoined()
is then used to join the array ofString
back into a singleString
.
Remove the word optional when assigning two variable values to label
Simply add the 2nd var2 to the if let
:
if let var1 = defaultValues.string(forKey: "var1"), let var2 = defaultValues.string(forKey: "var2") {
label1.text = "\(var1) \(var2)"
} else {
// One (or both) of the two were nil. Do something else as needed
}
If you want to show just one of the vars if the other is nil, then break it up:
let var1 = defaultValues.string(forKey: "var1")
let var2 = defaultValues.string(forKey: "var2")
if let var1 = var1 {
if let var2 = var2 {
// Both are set
label1.text = "\(var1) \(var2)"
} else {
// Just var1 is set
label1.text = var1
}
} else if let var2 = var2 {
// Only var2 is set
label1.text = var2
} else {
// Neither is set
label1.text = "Oops!"
}
Related Topics
Swift Repl: How to Import, Load, Evaluate, or Require a .Swift File
Different Ways to Initialize a Dictionary in Swift
Access Input from Uialertcontroller
Swift: Determine What Object Called a Function
Swift Write/Save/Move a Document File to Icloud Drive
How to Draw Text in PDF Context in Swift
How to Determine the Type of a Variable in Swift
One-Line Closure Without Return Type
Dispatchsourcetimer and Swift 3.0
Swift: 'Hashable.Hashvalue' Is Deprecated as a Protocol Requirement;
Override Func Error in Swift 2
Swift 3: the Difference Between Public and Internal Access Modifiers
Swift - Unit Testing Private Variables and Methods
How to Silence a Warning in Swift