Array with multiple values per index? - swift

I'm learning swift, and I do the sololearn course to get some knowledge, but I bumped into something that I don't understand.
It is about modifying an array's values. The questionable part states the following:
In the following example, the elements with index 1, 2, 3 are replaced with two new values.
shoppingList[1...3] = [“Bananas”, “Oranges”]
How can an one dimensional array take more than one value per index? And how do I access them? Am I misunderstanding something?

What this code does is replacing the element of shoppingList in the 1...3 range using Array.subscript(_:)
That means considering this array:
var shoppingList = ["Apples", "Strawberries", "Pears", "Pineaples"]
that with:
shoppingList[1...3] = ["Bananas", "Oranges"]
Strawberries, Pears and Pineaples will be replaced by Bananas and Oranges.
so the resulting array will be: Apples, Bananas, Oranges

When you assign to a range of indices in an array (array[1...3]), those elements are removed from the array and the new elements are 'slotted in' in their place. This can result in the array growing or shrinking.
var array = Array(0...5)
// [0, 1, 2, 3, 4, 5]
array[1...3] = [-1, -2]
// [0, -1, -2, 3, 4]
Notice how our array's length is now one element shorter.

You could use a tuple (Value, Value), or create a struct to handle your values there, in fact if you plan to reuse this pair or value, a struct is the way to go.
By the way, there's no need to add [1..3], just put the values inside the brackets.
struct Value {
var name: String
var lastName: String
}
let values = [Value(name: "Mary", lastName: "Queen"), Value(name: "John", lastName: "Black")]
// Access to properties
let lastName = values[1].lastName
// OR
let tuples = [("Mary", "Queen"), ("John", "Black")]
let lastNameTuple = tuples[1].1
Hope you're enjoying Swift!

Related

Populate a multidimensional array with a loop [duplicate]

This question already has answers here:
Error: "array index out of range" in multidimensional array
(2 answers)
Closed 6 years ago.
I'm trying to populate a multidimensional array with this code:
var array = [[Int]]()
for i in 0...3 {
for j in 0...3{
array[i][j] = i + j <<- Error
}
}
But I get an error:
fatal error: Index out of range
What am I doing wrong?
[[Int]] is not a multidimensional array. It is an array of arrays. That's a very different thing. For example, in an array of arrays, each row may have a different number of columns. It's generally a bad idea to use a nested array as a multidimensional array, particularly a mutable one. It's often incredibly inefficient to modify because it causes a lot of copying every time you change it.
Swift doesn't have a multidimensional array type. If you really need one, you generally have to build it yourself, or redesign to avoid it. If it's small enough, and doesn't change much, it's not that big a deal, but don't let them get large.
That said, the problem is that element [0][0] doesn't exist because you didn't create it. You'd need to initialize the array this way before using it:
var array = Array(repeating: Array(repeating: 0, count: 4), count: 4)
This creates an array of 4 arrays of 4 zeros.
If you want specifically the layout you describe, possibly a better approach is mapping, which is likely going to be more efficient (since it doesn't keep modifying the nested array):
let array = (0...3).map { i in
(0...3).map { j in
return i + j
}
}
Calling array[i][j] is for elements that are already there. You cannot use it to initialize the array, because currently it is just an empty array. You should be using .append instead. Keep in mind that this actually isn't a multi-dimensional array like Rob Napier states, but it accomplishes the same goal in this scenario. Try something like this:
var array = [[Int]]()
for i in 0...3 {
var subArray = [Int]()
for j in 0...3 {
subArray.append(i + j)
}
array.append(subArray)
}
This prints:
[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6]]
Again, may not be the best approach, but this is just how you could do it in Swift.

Add new key value to all the elements in array of dictionary

I have a array of dictionary.
I need to add a new key and a value to all the elements of array of dictionary.
Please guide.
You need to extract the dictionary from the array, modify it and put back to the array, since arrays and dictionaries in Swift are value types.
Something like this should work for you:
var arrayofDict = [["1": 1], ["2": 2], ["3": 3]]
for i in 0..<arrayofDict.count {
var dict = arrayofDict[i]
dict["random"] = Int(arc4random_uniform(8)) //random integer value
arrayofDict[i] = dict
}
print(arrayofDict) //prints "[["1": 1, "random": 2], ["2": 2, "random": 0], ["random": 2, "3": 3]]\n"

Immutable Dictionary value change

Can we change any pair value in let type Dictionary in Swift Langauage.
like :
let arr2 : AnyObject[] = [1, "23", "hello"]
arr2[1] = 23
arr2 // output: [1,23,"hello"]
let arr1 :Dictionary<Int,AnyObject> = [1: "One" , 2 : 2]
arr1[2] = 4 // not posible error
arr1
In Case of Immutable Array we can change its value like above but not in case of Immutable
Dictionary. Why?
This is taken from The Swift Programming Language book:
For dictionaries, immutability also means that you cannot replace the
value for an existing key in the dictionary. An immutable dictionary’s
contents cannot be changed once they are set.
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.
Array declared with let has only immutable length. Contents can still be changed.
Dictionary declared with let is completely immutable, you can't change contents of it. If you want, you must use var instead of let.
Swift has changed a lot since then.
Array and Dictionary are value types. When declared with let, they cannot change any more. Especially, one cannot re-assign them, or the elements in them.
But if the type of the elements is reference type, you can change the properties of the elements in Array or Dictionary.
Here is a sample.(run in Xcode6 beta-6)
class Point {
var x = 0
var y = 0
}
let valueArr: [Int] = [1, 2, 3, 4]
let refArr: [Point] = [Point(), Point()]
valueArr[0] = -1 // error
refArr[0] = Point() // error
refArr[0].x = 1
let valueDict: [Int : Int] = [1: 1, 2: 2]
let refDict: [Int: Point] = [1: Point(), 2: Point()]
valueDict[1] = -1 //error
refDict[1] = Point() //error
refDict[1]!.x = -1

Not able to print values of array in swift

I am not able to print array values in swift. My code is:
var array = 1...10
println(array)
The result is:
VSs5Range (has 2 children)
But when I try to print the following array, it works:
var array = [1,2,3,4,5,6,7,8,9,10]
println(array)
Result is:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Why isn't the first one printing correctly?
The expression 1...10 returns a Range, not an Array. Internally, a Range stores two values (a start and an end); an Array, on he other hand, is a dynamic structure containing "n" values.
As explained,
var array = 1...10
array, in this case, is a Range object, not an array
If you want to print its content do this (changed the name to something more suitable)
var range = 1...10
for value in range
{
println(value)
}

How to add integer to array (with explicite int index) in swift?

I read swift handbook and was trying to do some exercises. But I run into a problem and I do not know if I do something wrong or if xCode 6 beta is just buggy.
// Playground - noun: a place where people can play
import Cocoa
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
var largest = 0
var lastLargest = Integer[]()
var index = 0
for (kind, numbers) in interestingNumbers {
for number in numbers {
if number > largest {
//lastLargest[index] = number
index++
largest = number
}
}
}
index
lastLargest
largest
As soon as I uncomment lastLargest[index] = number I do not get any results on right side in playground. Nor I get any infos about index, lastLargest or largest.
Following example does not work either:
var index2 = 0
var lastLargest2 = Integer[]()
lastLargest2[index2] = 1
index2++
lastLargest2[index2] = 2
You are appending using an out of bound array-index. Don't do that. Instead, use append:
lastLargest.append(number)
From Apple's documentation:
You can’t use subscript syntax to append a new item to the end of an array. If you try to use subscript syntax to retrieve or set a value for an index that is outside of an array’s existing bounds, you will trigger a runtime error.
When you're using explicit indexes (subscript notation) to set values in a mutable array, some value must already exist in that array at that index. When you use subscript notation, you're essentially using a 'set', rather than a 'set and add if necessary'.
As a result, you should be using:
lastLargest.insert(number, atIndex: index)
If you want to insert a new item. This will let you insert an item at the specified index, assuming your collection's size is already greater than or equal to the index you're trying to replace.