2D array Swift goes out of bounds when appending arrays [duplicate] - arrays

This question already has answers here:
Why is this array out of index?
(2 answers)
Closed 4 years ago.
I want to append elements from one 2D array to the another 2D array, but I get fatal error index out of bound.
the code is as follows:
var array = [["a", "b", "c"], ["d","e","f"],["g","h","i"]]
var array2 = [[String]]()
var x = array.count
var y = array[1].count
for j in 0..<x {
for i in 0..<y {
array2[j].append(array[j][i])
}
}
print(array2)
please don't tell me to just copy the array as this is not what I need, I am using this procedure to do something more complex than just copying an array.
Any suggestions as to why it goes out of bounds?
thanks

array2[j] doesn't exist as it's just an empty array.
It would be much easier to do this:
var array = [["a", "b", "c"], ["d","e","f"],["g","h","i"]]
var array2 = [[String]]()
for item in array {
array2.append(item)
}
print(array2)
[["a", "b", "c"], ["d", "e", "f"], ["g", "h", "i"]]
But that is just copying the array exactly. You should provide a more precise example of what you are trying to achieve.
Another option (Which makes your current code work) is to create a 'row' in the first loop ready for insertion:
var array = [["a", "b", "c"], ["d","e","f"],["g","h","i"]]
var array2 = [[String]]()
var x = array.count
var y = array[1].count
for j in 0..<x {
array2.append([String]())
for i in 0..<y {
array2[j].append(array[j][i])
}
}
print(array2)
Which gives the same output:
[["a", "b", "c"], ["d", "e", "f"], ["g", "h", "i"]]

It is going out of bounds because array2[0] doesn't exist. You need to create an an empty array there before appending to it. Then append that array to the outer array.
var array = [["a", "b", "c"], ["d","e","f"],["g","h","i"]]
var array2 = [[String]]()
for j in 0..<array.count {
var stringArray: [String] = []
for i in 0..<array[j].count {
stringArray.append(array[j][i])
}
array2.append(stringArray)
}
print(array2)

Related

Get items with the same position from multidimensional array in Swift 5

I can't find the best way to do this.
I have an array with 3 arrays in there(this never change)
var ancho = [String]()
var largo = [String]()
var cantidad = [String]()
var arrayDeCortes = [ancho,largo,cantidad]
arrayDeCortes = [[a,b,c,d,..],[e,f,g,h,..],[i,j,k,l,..]]
I need to get this:
[a,e,i]
[b,f,j]
[c,g,k]
[d,h,l]
My problem is that I don't know how many items there is in each array(ancho,largo,cantidad)
and how access to all of them.
I hope you understand me
You can use reduce(into:_:) function of Array like this:
let arrayDeCortes = [["a","b","c","d"],["e","f","g","h"],["i","j","k","l"]]
let arrays = arrayDeCortes.reduce(into: [[String]]()) { (result, array) in
array.enumerated().forEach {
if $0.offset < result.count {
result[$0.offset].append($0.element)
} else {
result.append([$0.element])
}
}
}
print(arrays)
// [["a", "e", "i"], ["b", "f", "j"], ["c", "g", "k"], ["d", "h", "l"]]
Edit: As #Alexander mentioned in the comments, there is a simpler way of achieving this by using zip(_:_:) function twice.
The following will return an array of tuples:
var widths = ["a","b","c","d"]
var heights = ["e","f","g","h"]
var quantities = ["i","j","k","l"]
let result = zip(widths, zip(heights, quantities)).map { width, pair in
(width, pair.0, pair.1)
}
print(result)
// [("a", "e", "i"), ("b", "f", "j"), ("c", "g", "k"), ("d", "h", "l")]

Turn 1d array into 2d array in swift [duplicate]

This question already has answers here:
How can split from string to array by chunks of given size
(9 answers)
Closed 3 years ago.
If I have a one-dimensional array:
oneDimArray = [1,2,3,4,5,6,7,8,9]
and I already have a 3X3 two-dimensional array with the right amount of slots to fit the numbers
twoDimArray = [[0,0,0], [0,0,0], [0,0,0]]
...how do I fit the oneDimArray numbers into the twoDimArray, like:
[[1,2,3], [4,5,6], [7,8,9]]
?
I know I can do this with a couple of nested for-loops, but is there a simpler, functional way to do this?
Here is one way to do it. Make an iterator out of your one dimensional array, and then use map and compactMap along with .next() to replace the values of the twoDimArray to create the newArray:
let oneDimArray = [1,2,3,4,5,6,7,8,9]
let twoDimArray = [[0,0,0], [0,0,0], [0,0,0]]
var iter = oneDimArray.makeIterator()
let newArray = twoDimArray.map { $0.compactMap { _ in iter.next() } }
print(newArray)
Output
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
A nice feature of this technique is that you can easily fill in any pattern of array, and not just create a fixed 3x3 one for instance:
let oneDimArray = [1,2,3,4,5,6,7,8,9,10]
let patternArray = [[0], [0,0], [0,0,0], [0,0,0,0]]
var iter = oneDimArray.makeIterator()
let newArray = patternArray.map { $0.compactMap { _ in iter.next() } }
print(newArray)
Output
[[1], [2, 3], [4, 5, 6], [7, 8, 9, 10]]
A generic function
We can turn this into a generic function that can replace the values of a 2D array with those of a 1D array. Note that the types of the values in the arrays can be different if you like:
func overlay<T, U>(_ array: [[T]], values: [U]) -> [[U]] {
var iter = values.makeIterator()
return array.map { $0.compactMap { _ in iter.next() }}
}
// Create an 2D array of strings from this pattern
let patternArray = [[0], [0,0], [0,0,0], [0,0,0,0]]
print(overlay(patternArray, values: ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]))
Output
[["a"], ["b", "c"], ["d", "e", "f"], ["g", "h", "i", "j"]]
You can loop over index and value using enumerated and then calculate the correct postion using % and /
for (index, num) in oneDimArray.enumerated() {
twoDimArray[index / 3][index % 3] = num
}
var index = 0
twoDimArray.indices.forEach { (outerInd) in
twoDimArray[outerInd].indices.forEach { (innerInd) in
twoDimArray[outerInd][innerInd] = oneDimArray[index]
index += 1
}
}
for i in twoDimArray.indices {
for j in twoDimArray[i].indices {
twoDimArray[i][j] = oneDimArray.removeFirst();
}
}

Swift 3 - Check if a string exist inside an array and sort it

I have this special array var myArray : [Array<String>] = [["a"],["b"],["c"]]
I want to detect if "a" is already inside myArray
and after i would like to sort my array alphabetically but i havn't found any function to do all these things for my array
To find if your [[String]] contains "a", you can use contains twice:
var myArray : [Array<String>] = [["a"],["b"],["c"]]
if myArray.contains(where: { $0.contains("a") }) {
print("a found")
}
To sort the inner arrays, apply map to the outer array and sort each element:
var myArray : [Array<String>] = [["c", "a"], ["e", "b"], ["d"]]
let sorted = myArray.map { $0.sorted() }
print(sorted)
[["a", "c"], ["b", "e"], ["d"]]

Create dictionary in swift with array of strings as value

When creating a dictionary in swift with array of strings as value as follows:
lazy var info : Dictionary = {
var dictionary = [String: [String]]()
dictionary["Key1"] = ["A", "B", "C"]
dictionary["Key2"] = ["D", "E", "F"]
return dictionary
}()
Cannot assign to immutable expression of type 'Value?'
Any ideas whats wrong here?
I've seen your own answer, which works, but there's a better way: use a Swift dictionary by declaring its proper type, in your case [String: [String]]:
lazy var info : [String: [String]] = {
var dictionary = [String: [String]]()
dictionary["Key1"] = ["A", "B", "C"]
dictionary["Key2"] = ["D", "E", "F"]
return dictionary
}()
Change
lazy var info : Dictionary = {
var dictionary = [String: [String]]()
dictionary["Key1"] = ["A", "B", "C"]
dictionary["Key2"] = ["D", "E", "F"]
return dictionary
}()
to
lazy var info : NSDictionary = {
var dictionary = [String: [String]]()
dictionary["Key1"] = ["A", "B", "C"]
dictionary["Key2"] = ["D", "E", "F"]
return dictionary
}()
and all is good :)

Xcode Swift check if array contains object

I have this array :
var preferiti : [ModalHomeLine!] = []
I want to check if the array contains the same object.
if the object exists {
} else {
var addPrf = ModalHomeLine(titolo: nomeLinea, link: linkNumeroLinea, immagine : immagine, numero : titoloLinea)
preferiti.append(addPrf)
}
Swift has a generic contains function:
contains([1,2,3,4],0) -> false
contains([1,2,3,4],3) -> true
So it sounds like you want an array without duplicate objects. In cases like this, a set is what you want. Surprisingly, Swift doesn't have a set, so you can either create your own or use NSSet, which would look something like this:
let myset = NSMutableSet()
myset.addObject("a") // ["a"]
myset.addObject("b") // ["a", "b"]
myset.addObject("c") // ["a", "b", "c"]
myset.addObject("a") // ["a", "b", "c"] NOTE: this doesn't do anything because "a" is already in the set.
UPDATE:
Swift 1.2 added a set type! Now you can do something like
let mySet = Set<String>()
mySet.insert("a") // ["a"]
mySet.insert("b") // ["a", "b"]
mySet.insert("c") // ["a", "b", "c"]
mySet.insert("a") // ["a", "b", "c"] NOTE: this doesn't do anything because "a" is already in the set.

Resources