Welcome to FutureAppLaboratory

v=(*^ワ^*)=v

Learning Swift Part 4 - Strings and Characters

| Comments

Just some notes after reading Apple’s official online guide. Most code are from the guide, with some modification by me.

===== Full Notes =====

Strings and Characters

  • String Literals
1
    let someString = "..."
  • Initializing an Empty String
1
2
3
4
5
6
7
    var emptyString = ""               // empty string literal
    var anotherEmptyString = String()  // initializer syntax
    // these two strings are both empty, and are equivalent to each other

    if emptyString.isEmpty {
        println("Nothing to see here")
    }
  • String Mutability
1
2
3
4
5
6
7
    var variableString = "Horse"
    variableString += " and carriage"
    // variableString is now "Horse and carriage"

    let constantString = "Highlander"
    constantString += " and another Highlander"
    // this reports a compile-time error - a constant string cannot be modified
  • Strings Are Value Types

    • Swift’s String type is a value type. If you create a new String value, that String value is copied when it is passed to a function or method, or when it is assigned to a constant or variable. In each case, a new copy of the existing String value is created, and the new copy is passed or assigned, not the original version.

    • NSString in obj-c is NOT value type.

  • Working with Characters
1
2
3
4
5
6
    for character in "Dog!🐶" {
        println(character)
    }

    // a single character
    let yenSign: Character = "¥"
  • Concatenating Strings and Characters
1
2
3
4
5
6
7
8
9
10
11
12
    let string1 = "hello"
    let string2 = " there"
    var welcome = string1 + string2
    // welcome now equals "hello there"

    var instruction = "look over"
    instruction += string2
    // instruction now equals "look over there"

    let exclamationMark: Character = "!"
    welcome.append(exclamationMark)
    // welcome now equals "hello there!"
  • String Interpolation
1
2
3
    let multiplier = 3
    let message = "\(multiplier) times 2.5 is \(Double(multiplier) * 2.5)"
    // message is "3 times 2.5 is 7.5"
  • Unicode Scalars

  • Special Unicode Characters in String Literals

1
2
3
4
5
    let wiseWords = "\"Imagination is more important than knowledge\" - Einstein"
    // "Imagination is more important than knowledge" - Einstein
    let dollarSign = "\u{24}"        // $,  Unicode scalar U+0024
    let blackHeart = "\u{2665}"      // ♥,  Unicode scalar U+2665
    let sparklingHeart = "\u{1F496}" // 💖, Unicode scalar U+1F496
  • Extended Grapheme Clusters
1
2
3
4
5
6
7
8
9
10
    let eAcute: Character = "\u{E9}"                         // é
    let combinedEAcute: Character = "\u{65}\u{301}"          // e followed by ́
    // eAcute is é, combinedEAcute is é

    let precomposed: Character = "\u{D55C}"                  // 한
    let decomposed: Character = "\u{1112}\u{1161}\u{11AB}"   // ᄒ, ᅡ, ᆫ
    // precomposed is 한, decomposed is 한

    let enclosedEAcute: Character = "\u{E9}\u{20DD}"
    // enclosedEAcute is é⃝
  • Counting Characters
1
2
3
4
5
6
7
8
9
10
11
12
    let unusualMenagerie = "Koala 🐨, Snail 🐌, Penguin 🐧, Dromedary 🐪"
    println("unusualMenagerie has \(countElements(unusualMenagerie)) characters")
    // prints "unusualMenagerie has 40 characters"

    var word = "cafe"
    println("the number of characters in \(word) is \(countElements(word))
    // prints "the number of characters in cafe is 4"

    word += "\u{301}"    // COMBINING ACUTE ACCENT, U+0301

    println("the number of characters in \(word) is \(countElements(word))
    // prints "the number of characters in café is 4"
  • String and Character Equality
1
2
3
4
5
6
    let quotation = "We're a lot alike, you and I."
    let sameQuotation = "We're a lot alike, you and I."
    if quotation == sameQuotation {
        println("These two strings are considered equal")
    }
    // prints "These two strings are considered equal"
  • Two String values (or two Character values) are considered equal if their extended grapheme clusters are canonically equivalent.
1
2
3
4
5
6
7
8
9
10
    // "Voulez-vous un café?" using LATIN SMALL LETTER E WITH ACUTE
    let eAcuteQuestion = "Voulez-vous un caf\u{E9}?"

    // "Voulez-vous un café?" using LATIN SMALL LETTER E and COMBINING ACUTE ACCENT
    let combinedEAcuteQuestion = "Voulez-vous un caf\u{65}\u{301}?"

    if eAcuteQuestion == combinedEAcuteQuestion {
        println("These two strings are considered equal")
    }
    // prints "These two strings are considered equal"
  • Conversely, LATIN CAPITAL LETTER A (U+0041, or “A”), as used in English, is not equivalent to CYRILLIC CAPITAL LETTER A (U+0410, or “А”).
1
2
3
4
5
6
7
8
    let latinCapitalLetterA: Character = "\u{41}"

    let cyrillicCapitalLetterA: Character = "\u{0410}"

    if latinCapitalLetterA != cyrillicCapitalLetterA {
        println("These two characters are not equivalent")
    }
    // prints "These two characters are not equivalent"
  • Prefix and Suffix Equality
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
    let romeoAndJuliet = [
        "Act 1 Scene 1: Verona, A public place",
        "Act 1 Scene 2: Capulet's mansion",
        "Act 1 Scene 3: A room in Capulet's mansion",
        "Act 1 Scene 4: A street outside Capulet's mansion",
        "Act 1 Scene 5: The Great Hall in Capulet's mansion",
        "Act 2 Scene 1: Outside Capulet's mansion",
        "Act 2 Scene 2: Capulet's orchard",
        "Act 2 Scene 3: Outside Friar Lawrence's cell",
        "Act 2 Scene 4: A street in Verona",
        "Act 2 Scene 5: Capulet's mansion",
        "Act 2 Scene 6: Friar Lawrence's cell"
    ]

    var act1SceneCount = 0
    for scene in romeoAndJuliet {
        if scene.hasPrefix("Act 1 ") {
            ++act1SceneCount
        }
    }
    println("There are \(act1SceneCount) scenes in Act 1")
    // prints "There are 5 scenes in Act 1"

    var mansionCount = 0
    var cellCount = 0
    for scene in romeoAndJuliet {
        if scene.hasSuffix("Capulet's mansion") {
            ++mansionCount
        } else if scene.hasSuffix("Friar Lawrence's cell") {
            ++cellCount
        }
    }
    println("\(mansionCount) mansion scenes; \(cellCount) cell scenes")
    // prints "6 mansion scenes; 2 cell scenes"
  • A collection of UTF-8 code units (accessed with the string’s utf8 property)

  • A collection of UTF-16 code units (accessed with the string’s utf16 property)

  • A collection of 21-bit Unicode scalar values, equivalent to the string’s UTF-32 encoding form (accessed with the string’s unicodeScalars property)

  • UTF-8 Representation

1
2
3
4
5
6
7
    let dogString = "Dog‼🐶"

    for codeUnit in dogString.utf8 {
        print("\(codeUnit) ")
    }
    print("\n")
    // 68 111 103 226 128 188 240 159 144 182
  • UTF-16 Representation
1
2
3
4
5
    for codeUnit in dogString.utf16 {
        print("\(codeUnit) ")
    }
    print("\n")
    // 68 111 103 8252 55357 56374
  • Unicode Scalar Representation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    for scalar in dogString.unicodeScalars {
        print("\(scalar.value) ")
    }
    print("\n")
    // 68 111 103 8252 128054

    for scalar in dogString.unicodeScalars {
        println("\(scalar) ")
    }
    // D
    // o
    // g
    // ‼
    // 🐶

Comments