In what order when add item to "map" in swift? - swift

An example in swift tour in https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/GuidedTour.html#//apple_ref/doc/uid/TP40014097-CH2-ID1
var occupations = [
"Malcolm": "Captain",
"Kaylee": "Mechanic",
]
occupations["Jayne"] = "Public Relations"
The final result of occupations is :
["Kaylee": "Mechanic", "Jayne": "Public Relations", "Malcolm": "Captain"]
My question:
Is var occupations a Map?
In what order does new item be added?

The existing answers are highly likely to be confusing depending on what sort of programming background you come from.
var occupations = [
"Malcolm": "Captain",
"Kaylee": "Mechanic",
]
occupations["Jayne"] = "Public Relations"
Given that code snippet, the type of occupations is a Swift Dictionary. As the other answers point out, a dictionary, in Swift, is a collection of key-value pairs.
Other languages have a similar data structure, but may refer to it by a different name.
C++'s map type
.NET's Hashtable type
Java's HashMap type
Objective-C's NSDictionary type
The list could go on. But these all represent roughly the same data structure: a store of key & value pairs.
In Swift, dictionaries do not have an order. Any perceived ordering you notice from printing or iterating over items in a dictionary is just that--perceived. It should not be relied on.
If you need an ordered dictionary, you will need to implement it on your own. Although I'm sure someone has probably already implemented it and you can find it on github. A very simple implementation for an ordered pairs of data could simply involve an array of tuples, but you wouldn't be able to do the same key look up you can with dictionaries.
What is important here is that there is no defined order for data in a Swift dictionary, so any perceived ordering that is happening should not be relied on.

"occupations" is a dictionary (also known as a hash in some languages). It is key-value paired which means that the keys are in no particular order but each unique key is only tied to a single value (which can of course take the form of an array or another dictionary, but still counts as one value assigned to one key).
"Map" is a function that takes a list (such as the keys or values of "occupations") and returns an array of the original list with a function applied to it.
For example
(0..<4).map({$0 + 1})
Returns an array of [1, 2, 3, 4] because the $0 is Swift shorthand for "the value of the original array that am currently applying this function to.
As mentioned in the answers above, when an item is added to a dictionary its position is unimportant, as the dictionary is not by nature sorted like an array would be.

To turn Eric and Luk's comments into an official answer:
Your var 'occupations' is a Swift Dictionary object.
A Dictionary in Swift (and Objective-C as well) does not have any order at all. It is an "unordered collection."As Luk says, it's a key-value store. You save and retrieve values using a key.
Your questions:
Is var occupations a Map?
EDIT:
It's not called a Map in iOS, but it the equivalent of a map in other languages like C#, C++, and Java.
In what order does new item be added?
Dictionaries do no have any order whatsoever.

Related

Swift Disadvantages Array of Any

If I store a Tuple
var person = ("Steve", 22)
I cannot add more data easily into the structure.
However, if I use an array of Any
let steve: [Any] = ["Steve", 22]
I can easily add the elements.
Surely there are no real advantages to using a Tuple and we just always use an array of Any?
Any is weakly typed so you lose all of the static type checking guarantees that you get with strong types, including tuples. In addition, you cannot index out of bounds at run time on a tuple like you can with an array since the compiler knows how many components there are and it will fail to compile, and since a tuple is basically an anonymous struct, you can also name the components to make them more meaningful, which you cannot do with an array. You also pay a performance penalty for the array of Any since your data has to be boxed in the Any where as a tuple is just a struct and its components are not boxed.

Tuple vs. Object in Swift

I have read about the differences in Tuples and Dictionaries / Arrays, but I have yet to come across a post on Stack Overflow explaining the difference between a Tuple and an Object in Swift.
The reason I ask is that from experience, it seems that a Tuple could be interchangeable with an Object in Swift in many circumstances (especially in those where the object only holds other objects or data), but could lead to inconsistent / messy code.
In Swift, is there a time to use a Tuple and a time to use a basic Object based on performance or coding methodologies?
As vadian notes, Apple's advice is that tuples only be used for temporary values. this plays out. If you need to do almost anything non-trivial with a data structure, including store it in a property, you probably do not want a tuple. They're very limited.
I'd avoid the term "object" in this discussion. That's a vague, descriptive term that doesn't cleanly map to any particular data structure. The correct way to think of a tuple is as being in contrast to a struct. In principle, a tuple is just an anonymous struct, but in Swift a tuple is dramatically less flexible than a struct. Most significantly, you cannot add extensions to a tuple, and adding extensions is a core part of Swift programming.
Basically, about the time you're thinking that you need to label the fields of the tuple, you probably should be using a struct instead. Types as simple as "a point" are modeled as structs, not tuples.
So when would you ever use a tuple? Consider the follow (non-existent) method on Collection:
extension Collection {
func headTail() -> (Element?, SubSequence) {
return (first, dropFirst())
}
}
This is a good use of a tuple. It would be unhelpful to invent a special struct just to return this value, and callers will almost always want to destructure this anyway like:
let (head, tail) = list.headTail()
This is one thing that tuples can do that structs cannot (at least today; there is ongoing discussion of adding struct destructuring and pattern matching to Swift).
In Swift, Tuple is a Compound Type that holds some properties together which are built up from Objects of Swift Named Types for example class, struct and enum.
I would analogize Objects of these Named Types as minerals of chemical elements ( like carbon, calcium) and Tuple is just a kind of physical mixture of these minerals( eg a pack of 1 part of calcium ore and 3 parts of carbon ore). You can easily carry around this packed tuple and add it to “heat or press” method to return “limestone” your app use in construction.

Why isn't a Swift tuple considered a collection type?

In Swift, why isn't a tuple considered a collection type?
Of course this is fussbudget territory, but I find a certain amount of fussing helps me understand, retain, and organize what I'm learning.
I don't have inside knowledge of the motivations, but I can hopefully present some deeper understanding.
Type Safety
One of the primary goals of Swift is to enforce programming best practices to minimize human mistakes. One of these best practices is to ensure we always use specific types when we know them. In Swift, variables and constants always have explicit types and collections prefer to hold, say Strings, than AnyObjects if you know that it will be storing Strings.
Notably, every collection type in Swift may only hold one type of element. This includes Array, Dictionary, and Set.
Tuples are Compound Types
In Swift, there are two types of types: Named Types and Compound Types. Most types, including collection types, are named. Compound types, on the other hand, contain multiple named types in unique combinations. There are only two Compound Types: Function Types and Tuple Types. Tuple Types are different from collections in that:
Multiple Named Types can be bundled together in a Tuple Type without using AnyObject.
Each position can be given a textual label.
We can always anticipate how many values a tuple will be holding because we declared each position.
For more information, see the Types chapter of The Swift Programming Language.
Tuples Represent Objects
We typically don't think of a collection type as an object in itself. Instead, we think of it as a collection of objects. A tuple's labeled positions and multi-type functionality enable it to function more like an object than any collection. (Almost like a primitive Struct)
For example, you might consider an HTTP error to be a tuple with an error code (Int) and a description (String).
Tuples are often used as primitive approaches to temporary objects, such as returning multiple values from a function. They can be quickly dissected without indexing.
Additionally, each Tuple type has its own explicit type. For example, (Int, Int) is an entirely different type from (Int, Int, Int), which is an entirely different type from (Double, Double, Double).
For more on this, see "Tuples" in the The Basics chapter of The Swift Programming Language.
Tuples are Used in Fundamental Language Syntax
When we think of collection types, we think again of collections. Tuples, however, are used in fundamental places in the language that make Compound Type a more fitting title for them. For example, the Function Type is a Compound Tye that is used anytime you specify a function or closure. It is simply a tuple of parameters and a tuple of return values. Even Void is just a typealias for (), an empty tuple.
Additionally, tuples are in language syntax to temporarily bind values. For example, in a for-in loop you might use a tuple to iterate over a dictionary:
let dict = [1: "A", 2: "B", 3: "C"]
for (_, letter) in dict {
doSomething()
}
Here we use a tuple to iterate over only the values of the dictionary and ignore the keys.
We can do the same in Switch statements (excerpt from The Swift Programming Language):
let somePoint = (1, 1)
switch somePoint {
case (0, 0):
print("(0, 0) is at the origin")
case (_, 0):
print("(\(somePoint.0), 0) is on the x-axis")
case (0, _):
print("(0, \(somePoint.1)) is on the y-axis")
case (-2...2, -2...2):
print("(\(somePoint.0), \(somePoint.1)) is inside the box")
default:
print("(\(somePoint.0), \(somePoint.1)) is outside of the box")
}
// prints "(1, 1) is inside the box”
Because tuples are used in such fundamental places in language syntax, it wouldn't feel right for them to be bundled together with collection types.
SequenceType & CollectionType
One last thing to note is that a fundamental feature of CollectionType, which inherits much of this from SequenceType, is the ability to provide a safe Generator for iteration. For example, a for-in loop is possible because collections define a way to get the next item. Because tuples do not consist of the same types, and have a guaranteed number of items (after declaration), using them on the right of a for-in loop (instead of a traditional collection) would be less than intuitive.
If using it in a for-in loop, something designed to thrive with collections, seems less-than-intuitive for a tuple, than a tuple may deserve a different category.
For details on CollectionType, check out SwiftDoc.org. Note that a Generator providing iteration is required. Iterating a tuple would not be type safe and impose many unnecessary complexities, but making a tuple a collection is an interesting concept. It just might be too fundamental for that.

Swift: Converting a string into a variable name

I have variables with incremented numbers within, such as row0text, row1text, row2text, etc.
I've figured out how to dynamically create string versions of those variable names, but once I have those strings, how can I use them as actual variable names rather than strings in my code?
Example:
var row3text = "This is the value I need!"
var firstPart = "row"
var rowNumber = 3
var secondPart = "text"
var together = (firstPart+String(rowNumber)+secondPart)
// the below gives me the concatenated string of the three variables, but I'm looking for a way to have it return the value set at the top.
println (together)
Once I know how to do this, I'll be able to iterate through those variables using a for loop; it's just that at the moment I'm unsure of how to use that string as a variable name in my code.
Thanks!
Short Answer: There is no way to do this for good reason. Use arrays instead.
Long Answer:
Essentially you are looking for a way to define an unknown number of variables that are all linked together by their common format. You are looking to define an ordered set of elements of variable length. Why not just use an array?
Arrays are containers that allow you to store an ordered set or list of elements and access them by their ordered location, which is exactly what you're trying to do. See Apple's Swift Array Tutorial for further reading.
The advantage of arrays is that they are faster, far more convenient for larger sets of elements (and probably the same for smaller sets as well), and they come packaged with a ton of useful functionality. If you haven't worked with arrays before it is a bit of a learning curve but absolutely worth it.

Why in immutable array in swift value can be changed?

In swift a value in an immutable array can be changed but a value in an immutable dictionary can not be changed Why?
let imArray = ["Ram","Shyam","Bharat"]
imArray[2] = "Abhimanyu" // this change will be apply though it is immutable
EDIT: In Xcode 6 beta 3 notes, this is now changed. They now behave the same.
Array in Swift has been completely redesigned to have full value
semantics like Dictionary and String have always had in Swift.  This
resolves various mutability problems – now a 'let' array is
completely immutable, and a 'var' array is completely mutable –
composes properly with Dictionary and String, and solves other deeper
problems.  Value semantics may be surprising if you are used to
NSArray or C arrays: a copy of the array now produces a full and
independent copy of all of the elements using an efficient lazy copy
implementation.  This is a major change for Array, and there are
still some performance issues to be addressed.  Please see the Swift
Programming Language for more information.  (17192555)
I talked to an Apple engineer regarding this in WWDC
For arrays, when you define it as a constant, this means the backing buffer is constant, and thus you can change the contents of the buffer, but not swap out the buffer or modify its length.
For dictionaries, it is completely immutable.
Of course, if you think it should behave differently, submit a ticket to them!
From Apple's Swift documentation, under Mutability of Collections...
Immutability has a slightly different meaning for arrays, however. You are still not allowed to perform any action that has the potential to change the size of an immutable array, but you are allowed to set a new value for an existing index in the array. This enables Swift’s Array type to provide optimal performance for array operations when the size of an array is fixed.