A taste of Swift part 1

Updated vegaseat 2 Tallied Votes 1K Views Share

The Swift computer language is the brainchild of a number of Apple associates. In my humble opinion it shows some nice features, but also some warts. Part 1 (constants, variables, strings, tuples, arrays) explores a number of the features to give you a taste of the language. I hope I can follow this soon with part 2 (dictionaries, loops, if/else, switch/case,.functions, classes)

Even if you don't have an Apple computer, you can educate yourself using the Swift computer language. Just go onto the Swift online playground at swiftstub.com and start typing Swift code, enjoy the experience!

Note: Xcode 7.0 came out on 16sep2015 and with it the long awaited Swift2 version. The IDE contains a conversion option under the edit tab that will convert your Swift1 code to Swift2 syntax. The utility does a "Homer Simpson" type job.

ddanbe commented: Nice overview. +15
//
//  main.swift
//  Taste_of_swift1
//
// exploring Apple's Swift language, part 1
// vegaseat   5jun2015   used Swift version 1.2

import Foundation

// variables ...

// use 'let' to create a constant (cannot be changed later)
let Pi = 3.14

// use 'var' for variables (type is by inference)
var n = 30
// if you want value 30 to be a floating point value
// use Float (32bits) or Double (64bits)
var q: Double = 30
// or
var r = 30.0

// strings ...

// a String behaves like a doubly linked list of characters
// rather than an array, string handling is more complex, but
// it makes working with Unicode less error-prone
// strings are enclosed in ""
// there is no multiline string syntax (bummer!)

var s = "hippopotamus"
println(s.hasPrefix("hip"))  // true
println(s.hasSuffix("mud"))  // false
println(s.lowercaseString)   // hippopotamus
println(s.uppercaseString)   // HIPPOPOTAMUS
println(s.isEmpty)           // false
println(s.startIndex)        // 0

// gives the length of String s
println(s.endIndex)                  // 12
// gives the actual end index value (zero based)
println(s.endIndex.predecessor())    // 11

// accessing the characters of a string needs value of type index
// somewhat cumbersome!
println(s[s.startIndex])                          // h
println(s[s.endIndex.predecessor()])              // s
// at index 7 from start
println(s[advance(s.startIndex, 7)])              // t
// at index 8 from end
println(advance(s.endIndex.predecessor(), -8))    // 3
println(s[advance(s.endIndex.predecessor(), -8)]) // p

println(indices(s))   // 0..<12
// for ix in 0..<12 will not work!
for ix in indices(s) {
    print(s[ix]); print(" ") // h i p p o p o t a m u s
}
print("\n")

// add a character to the end
s.insert("!", atIndex: s.endIndex)
println(s)        // hippopotamus!

// remove character at end of string
s.removeAtIndex(s.endIndex.predecessor())
println(s)        // hippopotamus

var loc = "in water forests"
// splice a word into the string
loc.splice("near ", atIndex: advance(loc.startIndex, 9))
println(loc)      // in water near forests

// add the value of a variable/constant to a string
let name = "Frank"
// use \() to accomplish that
var hello = "I hope \(name) has a nice day!"

println(hello)  // I hope Frank has a nice day!

// you can concatenate strings with +
var sm1 = "cats"
var sm2 = " and "
var sm3 = "dogs"
println(sm1 + sm2 + sm3)   // cats and dogs

// append a character to a string
var c: Character = "?"
sm1.append(c)
println(sm1)     // cats?

// use a German "o umlaut" or ö (hex ascii value F6)
let oe = "\u{F6}"
println("dankesch\(oe)n")  // dankeschön

println("---------------------")

// tuples ...

// a tuple is a fixed sequence enclosed in ()
// mostly used to return mutiple values from a function
// a tuple allows mixed type elements
// for instance a string, an integer, a float, an array
let tuple = ("Einstein", 3, 25.7, [11, 22, 33])

println(tuple)  // (Einstein, 3, 25.7, [11, 22, 33])

// access the tuple
println(tuple.0)     // Einstein
println(tuple.3)     // [11, 22, 33]
println(tuple.3[1])  // 22

println("---------------------")

// arrays ...

var mynames:[String] = ["Frank", "Bob", "Tom"]
for name in mynames {
    println(name)
}
println(mynames)        // [Frank, Bob, Tom]
println(mynames[1])     // Bob
println(mynames.count)  // 3

// append() adds element to the end
// an array will increase its capacity as needed
mynames.append("Karl")
println(mynames)        // [Frank, Bob, Tom. Karl]
println(mynames.count)  // 4

// another way to add elements to an array
mynames += ["Moe", "Larry", "Curly"]
println(mynames)        // [Frank, Bob, Tom, Karl, Moe, Larry, Curly]

// subscripting with an integer range
// retrieve sub_array with elements at index 1 to 3
var sub = mynames[1...3]
println(sub)            // [Bob, Tom, Karl]

var values:[Int] = [1, 2, 3, 4, 5, 6, 7]
println(values)  // [1, 2, 3, 4, 5, 6, 7]

// replace elements at index 3 to 5 with new values
values[3...5] = [44, 55, 77]
println(values)  // [1, 2, 3, 44, 55, 77, 7]

// remove elements at index 0 to 3 (replace with empty array)
values[0...3] = []
println(values)  // [55, 77, 7]

// insert a new element at a given index
values.insert(33, atIndex: 2)
println(values)  // [55, 77, 33, 7]

// remove the last element
values.removeLast()
println(values)  // [55, 77, 33]

// { $0 < $1 } represents a closure (use spaces as shown)
// a closure is a little like lambda in Python
// sort in place ascending
values.sort { $0 < $1 }
println(values)  // [33, 55, 77]
// sort in place decending
values.sort { $0 > $1 }
println(values)  // [77, 55, 33]

var numbers: [Int] = [1, 2, 3, 4]
var sum = 0
for num in numbers {
    sum += num
}
// cast to Float to avoid integer division
var mean = Float(sum)/Float(numbers.count)
println("mean of \(numbers) = \(mean)")  // mean of [1, 2, 3, 4] = 2.5

// reverse the sequence
var nreverse = numbers.reverse()
println(nreverse)                // [4, 3, 2, 1]
println([11, 22, 33].reverse())  // [33, 22, 11]

// filter an array
// show the even numbers via closure { $0 % 2 == 0 }
var evens = numbers.filter { $0 % 2 == 0 }
println("evens of \(numbers) = \(evens)")  // evens of [1, 2, 3, 4] = [2, 4]

// map() an array using closure { $0 * 3 }
var times3 = numbers.map({ $0 * 3 })
println("\(numbers) times3 = \(times3)") // [1, 2, 3, 4] times3 = [3, 6, 9, 12]

// map() an array using simplified closure { $0 * $0 }
var squared = numbers.map { $0 * $0 }
println("\(numbers) squared = \(squared)") // [1, 2, 3, 4] squared = [1, 4, 9, 16]

// sum a numeric array via reduce() and closure { $0 + $1 }
var sum2 = numbers.reduce(0) { $0 + $1 }
println("sum of \(numbers) = \(sum2)")  // sum of [1, 2, 3, 4] = 10

// create an array of type Any
// allows array/list of mixed types
var mixed = [Any]()
mixed.append(123)
mixed.append(45.7)
mixed.append("poof")
println(mixed)      // [123, 45.7, poof]

println("---------------------")

// stride() seems to be a generator
for i in stride(from: 1, to: 20, by: 2) {
    print(i); print(" ")
}
// 1 3 5 7 9 11 13 15 17 19

println("\n---------------------")

// generate a random integer beween 0 and 9
var rand_int = Int(arc4random_uniform(10))
println(rand_int)  // eg. 7

println("---------------------")

// create an array of 10 random integers from 0 to 99
var randInts = [Int]()
for ix in 0...9 {
    randInts.append(Int(arc4random_uniform(100)))
}

println(randInts)  // eg. [5, 94, 33, 20, 17, 42, 59, 38, 81, 18]
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

Added type Any to the array. This allows you to use different types within the array. A little bit like a Python list object.

Coming to Swift after many years of C and Python you will see me using variable names with an underline in it. I am learning to use camelcase and actually like it.

I use Apple's free Xcode IDE to write my code. It can be used for C, C++, Objective C and Swift. Xcode also offers a playground for short Swift code explorations, and shows results as you type the code. Reminds me of iPython Notebook.

Swift is being developed by Apple to write applications for iMac (OS X), and iPad, iPhone, iWatch (iOS). A release for Linux OS is expected later this year. You can test drive Swift code on Windows OS using the playground at
http://swiftstub.com

Note that Swift version 2 is out in beta and has made a number of changes to the syntax and added error handling.

vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

Swift arrays expand on their own, you don't have to painstakingly allocate memory. A constant array (use 'let' instead of 'var') will not expand.

// this array is fixed in length
// only the elements can be changed
let constantArrInt = [1, 2, 3]
// this array can change in length
var variableArrInt = [1, 2, 3]
rubberman 1,355 Nearly a Posting Virtuoso Featured Poster

I will always be suspicious of vendor-written and distrubted programming languages. Lock-in is the least of the issues. Open standards exist for a reason. This is why I don't like Java - it isn't open, and sucks for a variety of reasons!

vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

Apple executive Craig Federighi announced that Swift will be open source and made available for Linux later this year.

As far as vendor-written languages are concerned, there are some top notch folks working for Apple and also Google, developing a newer language has a reason.

Swift is being developed by Apple to work seemlessly with the Cocoa GUI toolkit, and to replace the misserable Objective C syntax (MHO). As far as I can figure it out, Steve Jobs' NEXT computer company developed the UNIX based NextStep OS using Objective C. This became OpenStep and when Steve returned to Apple, their new operating system based on OpenStep became OS X (for the Mac) and iOS (for iPad and iPhone).

Apple developed Xcode, an IDE to allow the development of OS X and iOS applications with the GUI toolkit Cocoa (also came in with OpenStep). Right now the problem is that all of these things are still developing, and the older version examples litter the internet and are not necessarily compatible with newer verions. A nightmare is born!

In the other camp, Google is developing the Go language for their search engine efforts and to trastically reduce compile time experienced with the present C++ compiler. Go does not have a GUI toolkit, but is available for most operating systems.

vegaseat 1,735 DaniWeb's Hypocrite Team Colleague
// using formatted values string via % specifier
var avgTemp = 66.844322156
// Objective-C NSString and Swift String are interchangeable
var sf = String(format:"average = %.2fF", avgTemp)

println(sf)  // average = 66.84F

let total = 74.89
let tax = 5.71
let city = "Minden"
var percent = 100.0 * tax/total
let sf2 = String(format: "%@ salestax = %0.2f%%", city, percent)

println(sf2)     // Minden salestax = 7.62%

Tested out on the Swift playground. Part of the Xcode IDE.

vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

An example of a named tuple, actually an array of named tuples. With a named tuple you can use index numbers or more meaningful names ...

// create an empty array of tuples
var tdata = Array<(company: String, city: String, state: String, value: Float, profit: Float)>()

// populate some tuples
tdata = [
    ("KLV", "Miami", "FL", 540000, 119000),
    ("FST", "Oakland", "CA", 678000, 145000),
    ("CAMP", "Detroit", "MI", 942000, 177000)
]

// access tuple at array index 1
// item at tuple index 0
println(tdata[1].0)          // FST
// easier to read
println(tdata[1].company)    // FST
println(tdata[1].city)       // Oakland
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

Some date/time handling ...

println(NSDate())  // 2015-06-24 21:33:44 +0000

let format = NSDateFormatter()

format.dateFormat = "ddMMMyyy"
println(format.stringFromDate(NSDate())) // 24Jun2015

format.dateFormat = "MM/dd/yy"
println(format.stringFromDate(NSDate())) // 06/24/15

format.dateFormat = "EEE MM/dd/yy"
println(format.stringFromDate(NSDate())) // Wed 06/24/15

format.dateFormat = "EEE MMM dd, yyyy"
println(format.stringFromDate(NSDate())) // Wed Jun 24, 2015

format.dateFormat = "MM/dd/yyyy  HH:mm:ss"
println(format.stringFromDate(NSDate())) // 06/24/2015  14:32:13

// set an exact date/time value
let mydate = NSDateComponents()
mydate.year = 2015
mydate.month = 6
mydate.day = 15
mydate.hour = 15
mydate.minute = 11
mydate.second = 20

let birthday = NSCalendar.currentCalendar().dateFromComponents(mydate)!
println("Your birthday is on ...")
format.dateFormat = "EEE-MMM-dd HH:mm:ss"
println(format.stringFromDate(birthday)) // Mon-Jun-15 15:11:20

// or ...
let format2 = NSDateFormatter()
format2.dateStyle = NSDateFormatterStyle.MediumStyle
format2.timeStyle = .LongStyle

println(format2.stringFromDate(birthday)) // Jun 15, 2015, 3:11:20 PM PDT
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague
// split a string into an array at spaces
let s = "one two three"
let arr = s.componentsSeparatedByString(" ")
println(arr)  // [one, two, three]
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague
// simpler array creation (infer type string)
var mynames2 = ["Larry", "Jean", "Ronald"]
println(mynames2)   // [Larry, Jean, Ronald]
// replace name at index 0
mynames2[0] = "Peter"
println(mynames2)   // [Peter, Jean, Ronald]
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague
// more ways to populate an array ...
// create an array of integers and load it with ones
var ones = [Int](count: 5, repeatedValue: 1)
println(ones)  // [1, 1, 1, 1, 1]

// cast generator stride() to an Array ...
println(Array(stride(from: 1, to: 10, by: 2)))  // [1, 3, 5, 7, 9]
println(Array(stride(from: 0.1, to: 1.0, by: 0.2)))  // [0.1, 0.3, 0.5, 0.7, 0.9]
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

A closer look at a Swift array of tuples ...

// create an array of (name, age) tuples
// note that tuples can contain mixed types, but are immutable
var arrTup: [(String, Int)] = [("Tom", 24), ("Jim", 19), ("Bob", 75)]

// access via array [index] then tuple .index ...
println(arrTup[0].0)  // Tom
println(arrTup[0].1)  // 24
println(arrTup[1].0)  // Jim

// sort using a simplified closure
var sortName = arrTup.sorted({ $0.0 < $1.0 })
println(sortName)   // [(Bob, 75), (Jim, 19), (Tom, 24)]

var sortAge = arrTup.sorted({ $0.1 < $1.1 })
println(sortAge)   // [(Jim, 19), (Tom, 24), (Bob, 75)]

var sortAge2 = arrTup.sorted({ $0.1 > $1.1 })
println(sortAge2)  // [(Bob, 75), (Tom, 24), (Jim, 19)]
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

Manipulating an array of strings ...

// create array of strings
var arrStr = ["Tim", "Jimmy", "Roberto", "Albert"]
println(arrStr.count)      // 4
println(arrStr)            // [Tim, Jimmy, Roberto, Albert]
println(arrStr.reverse())  // [Albert, Roberto, Jimmy, Tim]
println(arrStr.sorted(<))  // [Albert, Jimmy, Roberto, Tim]
println(arrStr.sorted(>))  // [Tim, Roberto, Jimmy, Albert]
// sorted by size using a simplified closure
var bysize = arrStr.sorted({ count($0) > count($1) })
println(bysize)  // [Roberto, Albert, Jimmy, Tim]
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

From what I have learned up to this point, the Swift folks make a great effort to create a save language. The kind of language you want to use to write software for a driverless car with.

ddanbe 2,724 Professional Procrastinator Featured Poster

Referring to your first code listing.
You said that indexing a string is somewhat cumbersome. Indeed it is.
But the feature in the for loop on line 56 is a nice thing to have!
No more index out of range errors. :)

vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

@ddanbe, you are right, it is safer that way.
Type String in Swift is a structure. If you want your string to be an array of characters, you can easily do this ...

// cast a string to an array of characters
var arrChr = Array("abcdefg")

// now you can use [] indexing, but
// watch for index out of range errors
println(arrChr[1])      // b
println(arrChr[1...3])  // [b, c, d]

This approach most likely makes a mess out of unicode grapheme clusters!
Tested it, seems to work just fine!

vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

A note on tuples ...

// unpacking a (name, age, home) tuple
let tuplePerson = ("Klaus", 26, "Berlin")
var name, home: String
var age: Int

// unpack for name and home
(name, _, home) = tuplePerson
println((name, home))  // (Klaus, Berlin)

// unpack just for age
(_, age, _) = tuplePerson
println(age)  // 26

// tuple with external names, more readable
let tuplePerson2 = (name: "Klaus", age: 26, home: "Berlin")
println(tuplePerson2.name)  // Klaus
println(tuplePerson2.age)   // 26
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

Tested on the Swift playground ...

// sum the contents of a number array with reduce()
// reduce() takes two parameters, an initial value and a closure
var numbers2 = [1, 2, 3, 4, 5]
var sum2 = numbers2.reduce(0){ $0 + $1 }
println(sum2)     // 15

var numbers3 = [1.2, 2.7, 3.14, 4.4, 5.78]
var sum3 = numbers3.reduce(0){ $0 + $1 }
println(sum3)     // 17.22
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague
// another version of summation
// reduce(initial value, combine: function)
// in Swift "+" is a function
var numbers4 = [1, 2, 3, 4, 5]
var mySum4 = numbers4.reduce(0, combine: +)
println(mySum4)     // 15
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

Something tuples can be used for ...

var names = ["Abby", "Zoey"]
println(names)      // [Abby, Zoey]
// do a "tuple swap" ...
(names[1], names[0]) = (names[0], names[1])
println(names)      // [Zoey, Abby]

Reminds me of my Python days.

vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

Get the maximum/minimum value of an array ...

var arrStr2 = ["Tim", "Tom", "Tammy", "Abby", "Albert"]
// by unicode values in sequence
println(maxElement(arrStr2))  // Tom
println(minElement(arrStr2))  // Abby

Could of course be a numeric array too.

vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

Working with arrays and closures...

println(UnicodeScalar("a").value)  // 97
println(UnicodeScalar("z").value)  // 122

// create an array of characters from a to z
let chrArray = Array(97...122).map { UnicodeScalar($0) }
println(chrArray)  // [a, b, c, d, e, f, g, ...]
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

An interesting closure in map() ...

// sum the digits of an integer number ...
let number = 1234
// convert to array of characters
let chrArr = Array(String(number))
// convert to array of integers
var intArr = chrArr.map { chr in String(chr).toInt()! }
// sum up the integers and show
println(intArr.reduce(0, combine: +))  // 10
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

Counting down is simple ...

// counting down ...
for k in reverse(0...6) {
    println(k)
}
/*
6
5
4
3
2
1
0
*/
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

You could prioritize your life ...

// create an empty array of (priority, task) tuples
var myPriorities = Array<(priority: Int, task: String)>()
// load some tuples
myPriorities = [
    (3, "Take a bath"),
    (4, "Feed the dog"),
    (5, "Mow the lawn"),
    (1, "Jane's birthday"),
    (2, "Do tax filings")
]
// sort by priority (in place sort)
myPriorities.sort { $0.priority < $1.priority }

for priority in myPriorities {
    println(priority)
}

/*
(1, Jane's birthday)
(2, Do tax filings)
(3, Take a bath)
(4, Feed the dog)
(5, Mow the lawn)
*/
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

Could be the start of a guess a word game ...

// scramble/shuffle a string at random
// using the standard Fisher-Yates shuffle
func wordShuffle(word: String) -> String {
    var chrArr = Array(word)
    let size = chrArr.count
    for k in 0..<size {
        let a = k
        let b = Int(arc4random_uniform(UInt32(size)))
        // do a tuple swap
        (chrArr[a], chrArr[b]) = (chrArr[b], chrArr[a])
    }
    return "".join(chrArr.map { String($0) })
}

let word = "basket"
let scramledWord = wordShuffle(word)
println(scramledWord)  // eg. ketsab
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

Coming in the fall of 2015 ...
Swift2 replaces println() with just print() that has a newline default. The sort of thing that Python3 did to print(). There are some other syntax changes.
Good news, there will be a Swift 1-to-2 migrator utility to change Swift1 syntax to Swift2 syntax.

vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

Swift2 has come upon us bringing along a fair number of changes. I have taken the original Swift 1.2 snippet and run it through the migration utility. Just like in Python2 to Python3, print() is the obvious change, but there are some rather subtle changes too ...

//
//  main.swift
//  Taste_of_swift1
//
// exploring Apple's Swift language, part 1 
// as of Swift 2, String no longer conforms to CollectionType
// to get things to work s.characters is used a lot
// modified to work with Swift2  vegaseat   18sep2015

import Foundation

// variables ...

// use 'let' to create a constant (cannot be changed later)
let Pi = 3.14

// use 'var' for variables (type is by inference)
var n = 30
// if you want value 30 to be a floating point value
// use Float (32bits) or Double (64bits)
var q: Double = 30
// or
var r = 30.0

// strings ...

// in Swift String is a structure
// a String behaves like a doubly linked list of characters
// rather than an array, string handling is more complex, but
// it makes working with Unicode less error-prone
// strings are enclosed in ""
// there is no multiline string syntax (bummer!)
var s = "hippopotamus"
print(s.hasPrefix("hip"))  // true
print(s.hasSuffix("mud"))  // false
print(s.lowercaseString)   // hippopotamus
print(s.uppercaseString)   // HIPPOPOTAMUS
print(s.isEmpty)           // false
print(s.startIndex)        // 0

// gives the length of String s
print(s.endIndex)             // 12
print(s.characters.count)     // 12

// gives the actual end index value (zero based)
print(s.endIndex.predecessor())    // 11

// accessing the characters of a string needs value of type index
// somewhat cumbersome!
print(s[s.startIndex])                          // h
print(s[s.endIndex.predecessor()])              // s
// or ...
print(s[s.endIndex.advancedBy(-1)])
// at index 7 from start
print(s[s.startIndex.advancedBy(7)])              // t
// at index 8 from end
print(s.endIndex.predecessor().advancedBy(-8))    // 3
print(s[s.endIndex.predecessor().advancedBy(-8)]) // p

print(s.characters.indices)   // 0..<12
// for ix in 0..<12 will not work!
for ix in s.characters.indices {
    print(s[ix], terminator: " ") // h i p p o p o t a m u s}
}
print("")

// add a character to the end
s.insert("!", atIndex: s.endIndex)
// or s.extend("!")
print(s)        // hippopotamus!

// remove character at end of string
s.removeAtIndex(s.endIndex.predecessor())
print(s)        // hippopotamus

var loc = "in water forests"
// splice a word into the string
//loc.splice("near ", atIndex: loc.startIndex.advancedBy(9))
loc.insertContentsOf("near ".characters, at: loc.startIndex.advancedBy(9))
print(loc)      // in water near forests

print("---------------------")

// since String is a structure use the extension option
// to allow for integer indexing
extension String
{
    subscript(integerIndex: Int) -> Character {
        let index = startIndex.advancedBy(integerIndex)
        return self[index]
    }

    subscript(integerRange: Range<Int>) -> String {
        let start = startIndex.advancedBy(integerRange.startIndex)
        let end = startIndex.advancedBy(integerRange.endIndex)
        let range = Range(start: start, end: end)
        return self[range]
    }
}

let digits = "0123456789"
print(digits[5])      // 5
print(digits[4...6])  // 456

print("---------------------")

// add the value of a variable/constant to a string
let name = "Frank"
// use \() to accomplish that
var hello = "I hope \(name) has a nice day!"

print(hello)  // I hope Frank has a nice day!

// you can concatenate strings with +
var sm1 = "cats"
var sm2 = " and "
var sm3 = "dogs"
print(sm1 + sm2 + sm3)   // cats and dogs

// append a character to a string
var c: Character = "?"
sm1.append(c)
print(sm1)     // cats?

// use a German "o umlaut" or ö (hex ascii value F6)
let oe = "\u{F6}"
print("dankesch\(oe)n")  // dankeschön

print("---------------------")

// convert a numeric string
var sx = "12345679"
// add ! to remove option()
var nx = Int(sx)!
print(nx * 18)           // 222222222

// convert to Objective-C NSString to work
var sy = "3.14" as NSString
// there are also doubleValue, boolValue, intValue
var ny = sy.floatValue
print(ny + 1.1)         // 4.24

// convert a numeric string to a double
func str2double(s: String) -> Double {
    let n = NSNumberFormatter().numberFromString(s)
    return n!.doubleValue
}

var sz = "12.345"
var nz = str2double(sz)
print(nz * 10.0)        // 123.45

// convert a numeric string to a 32 bit integer
func str2int32(s: String) -> Int32 {
    let n = NSNumberFormatter().numberFromString(s)
    return n!.intValue
}

var nn = str2int32("12345679")
print(nn * 63)         // 777777777

print("---------------------")

// tuple ...
// a tuple is a fixed sequence enclosed in ()
// mostly used to return mutiple values from a function
// a tuple allows mixed type elements
// for instance a string, an integer, a float, an array
let tuple = ("Einstein", 3, 25.7, [11, 22, 33])

print(tuple)  // (Einstein, 3, 25.7, [11, 22, 33])

// access the tuple
print(tuple.0)     // Einstein
print(tuple.3)     // [11, 22, 33]
print(tuple.3[1])  // 22

// create an empty array of tuples
var tdata = Array<(company: String, city: String, state: String, value: Float, profit: Float)>()

// populate some tuples
tdata = [
    ("KLV", "Miami", "FL", 540000, 119000),
    ("FST", "Oakland", "CA", 678000, 145000),
    ("CAMP", "Detroit", "MI", 942000, 177000)
]

// access tuple at array index 1
// item at tuple index 0
print(tdata[1].0)          // FST
// easier to read
print(tdata[1].company)    // FST
print(tdata[1].city)       // Oakland

print("---------------------")

// arrays ...

// create name and type of empty array
// var cities = [String]()
// or ...
var cities: [String]
// then populate the array
cities = ["Boston", "London", "Berlin"]

// create name and type and populate
//var mynames:[String] = ["Frank", "Bob", "Tom"]
// simpler, let Swift infer the type
var mynames = ["Frank", "Bob", "Tom"]

for name in mynames {
    print(name)
}
print(mynames)        // [Frank, Bob, Tom]
print(mynames[1])     // Bob
print(mynames.count)  // 3

// append() adds element to the end
// an array will increase its capacity as needed
mynames.append("Karl")
print(mynames)        // [Frank, Bob, Tom. Karl]
print(mynames.count)  // 4

// another way to add elements to an array
mynames += ["Moe", "Larry", "Curly"]
print(mynames)        // [Frank, Bob, Tom, Karl, Moe, Larry, Curly]

// replace a name at a given index
// replaces "Frank" with "Peter"
mynames[0] = "Peter"

// subscripting with an integer range
// retrieve sub_array with elements at index 1 to 3
var sub = mynames[1...3]
print(sub)            // [Bob, Tom, Karl]

var values:[Int] = [1, 2, 3, 4, 5, 6, 7]
print(values)  // [1, 2, 3, 4, 5, 6, 7]

// replace elements at index 3 to 5 with new values
values[3...5] = [44, 55, 77]
print(values)  // [1, 2, 3, 44, 55, 77, 7]

// remove elements at index 0 to 3 (replace with empty array)
values[0...3] = []
print(values)  // [55, 77, 7]

// insert a new element at a given index
values.insert(33, atIndex: 2)
print(values)  // [55, 77, 33, 7]

// remove the last element
values.removeLast()
print(values)  // [55, 77, 33]

// { $0 < $1 } represents a closure (use spaces as shown)
// a closure is a little like lambda in Python
// sort in place ascending
values.sortInPlace { $0 < $1 }
print(values)  // [33, 55, 77]
// sort in place decending
values.sortInPlace { $0 > $1 }
print(values)  // [77, 55, 33]

var numbers: [Int] = [1, 2, 3, 4]
var sum = 0
for num in numbers {
    sum += num
}
// cast to Float to avoid integer division
var mean = Float(sum)/Float(numbers.count)
print("mean of \(numbers) = \(mean)")  // mean of [1, 2, 3, 4] = 2.5

// reverse the sequence
var nreverse = Array(numbers.reverse())
print(nreverse)                // [4, 3, 2, 1]
print(Array([11, 22, 33].reverse()))  // [33, 22, 11]

// filter an array
// show the even numbers via closure { $0 % 2 == 0 }
var evens = numbers.filter { $0 % 2 == 0 }
print("evens of \(numbers) = \(evens)")  // evens of [1, 2, 3, 4] = [2, 4]

// map() an array using closure { $0 * 3 }
var times3 = numbers.map({ $0 * 3 })
print("\(numbers) times3 = \(times3)") // [1, 2, 3, 4] times3 = [3, 6, 9, 12]

// map() an array using simplified closure { $0 * $0 }
var squared = numbers.map { $0 * $0 }
print("\(numbers) squared = \(squared)") // [1, 2, 3, 4] squared = [1, 4, 9, 16]

// sum a numeric array via reduce() and closure { $0 + $1 }
var sum2 = numbers.reduce(0) { $0 + $1 }
print("sum of \(numbers) = \(sum2)")  // sum of [1, 2, 3, 4] = 10

// create an array of type Any
// allows array/list of mixed types
var mixed = [Any]()
mixed.append(123)
mixed.append(45.7)
mixed.append("poof")
print(mixed)      // [123, 45.7, poof]

print("---------------------")

// stride() seems to be a generator
for i in 1.stride(to: 20, by: 2) {
    print(i, terminator: " ")
}
print("")
// 1 3 5 7 9 11 13 15 17 19

// other ways to create an array of integers
// stride() is a generator, cast it to an array
var arr2 = Array(1.stride(to: 14, by: 2))
print(arr2)        // [1, 3, 5, 7, 9, 11, 13]

print("\n---------------------")

// generate a random integer beween 0 and 9
var rand_int = Int(arc4random_uniform(10))
print(rand_int)  // eg. 7

print("---------------------")

// create an array of 10 random integers from 0 to 99
var randInts = [Int]()
for ix in 0...9 {
    randInts.append(Int(arc4random_uniform(100)))
}

print(randInts)  // eg. [5, 94, 33, 20, 17, 42, 59, 38, 81, 18]

// Python-like console user input
func input(prompt: String) -> String {
    print(prompt, terminator: "")
    let keyboard = NSFileHandle.fileHandleWithStandardInput()
    let inputData = keyboard.availableData
    // convert to a String, use ! to remove option()
    var str = String(NSString(data: inputData, encoding: NSUTF8StringEncoding)!)
    // remove trailing newline char from string
    str.removeAtIndex(str.endIndex.predecessor())
    return str
}

var name2 = input("Please enter your name: ")
print("Hello \(name2), nice name!")
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.