2

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?

3
  • (not familiar with Swift) you should be able to do a reduce operation or even a recursive algorithm. Not sure what the best tool Swift has for these. If you know the exact number of slots and they follow a pattern, you can derive locations mathematically and do it in a straight loop: threeDimArray[i / 3][i % 3] = oneDimArray[i] (where / performs integer division). Commented Jan 20, 2020 at 13:10
  • 1
    Why do you call a 2-dimensional array threeDimArray? Commented Jan 20, 2020 at 13:15
  • good point @MartinR - updated Commented Jan 20, 2020 at 13:16

4 Answers 4

9

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"]]
Sign up to request clarification or add additional context in comments.

Comments

4

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
}

Comments

2
var index = 0
twoDimArray.indices.forEach { (outerInd) in
    twoDimArray[outerInd].indices.forEach { (innerInd) in
        twoDimArray[outerInd][innerInd] = oneDimArray[index]
        index += 1
    }
}

Comments

0
for i in twoDimArray.indices {
    for j in twoDimArray[i].indices {
        twoDimArray[i][j] = oneDimArray.removeFirst();
    }
}

1 Comment

See "Explaining entirely code-based answers". While this might be technically correct it doesn't explain why it solves the problem or should be the selected answer. We should educate in addition to help solve the problem.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.