DEV Community

Cover image for Unrolling a Matrix
Matthew Palmer
Matthew Palmer

Posted on

Unrolling a Matrix

Introduction

You are The One... who will learn to unroll a matrix. I'm not Morpheus, but we're still going to be doing some pretty cool stuff in a virtual world today. 😉 Let's dive in!

The Matrix

Take a look at this array of arrays...

let matrix = [[1, 2, 3, 4],
              [12,13,14,5],
              [11,16,15,6],
              [10,9, 8, 7]];
Enter fullscreen mode Exit fullscreen mode

The idea behind matrix is to unroll all the numbers in order using a series of operations. Your output being:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

So, how would we accomplish this? Maybe we should break down the process logically. So far we know that the first move should count each element in the first array. The next should count the last element in each array. Afterwards, the bottom array should be mapped backwards. So on and so forth... You get where this is going!

Check out the blueprint:

function unroll(matrix){
    // top

    // right side

    // bottom in reverse 

    // left side
}
Enter fullscreen mode Exit fullscreen mode

First move

To make this a succinct process, we are going to be using the spread operator in every step. If you need a refresher on how the spread operator works, here is a link to a great resource.

Great, let's start with the first row!

function unroll(matrix){
    // top
    console.log(...matrix.shift())
    // right side

    // bottom in reverse 

    // left side
}
Enter fullscreen mode Exit fullscreen mode

We are using the shift() tool to return the first array within matrix, [1, 2, 3, 4]. The spread operator allows us to receive this information as 1 2 3 4. Simple enough, right?

Second move

function unroll(matrix){
    // top
    console.log(...matrix.shift())
    // right side
    console.log(...matrix.map(arr => arr.pop()))
    // bottom in reverse 

    // left side
}
Enter fullscreen mode Exit fullscreen mode

In this step, we are mapping over each array of arrays and using the .pop() tool to receive the very last number in each array. This returns 5 6 7.

Third move

function unroll(matrix){
    // top
    console.log(...matrix.shift())
    // right side
    console.log(...matrix.map(arr => arr.pop()))
    // bottom in reverse 
    console.log(...matrix.pop().reverse())
    // left side
}
Enter fullscreen mode Exit fullscreen mode

Looks a bit similar to our first move, right? Except this time, we are using both the .pop() and .reverse() method to get the values of the very last array in numerical order. Without .reverse(), we would get 10 9 8 7 instead. No bueno!

Last move

function unroll(matrix){
    // top
    console.log(...matrix.shift())
    // right side
    console.log(...matrix.map(arr => arr.pop()))
    // bottom in reverse 
    console.log(...matrix.pop().reverse())
    // left side
    console.log(...matrix.map(arr => arr.shift().reverse())
}
Enter fullscreen mode Exit fullscreen mode

Ahh, sweet order. It all makes sense now! We are mapping over each remaining array and pulling the first number off in .reverse()! Wonderful. But, there's something missing here... Something dynamic.

We as developers don't want to rewrite these steps whenever we encounter a much larger matrix. Given the fact that we still have a small matrix left...

let matrix = [[13, 14
              [16, 15]];
Enter fullscreen mode Exit fullscreen mode

How do we finish it off? Why, recursion of course!

function unroll(matrix){
    // top
    console.log(...matrix.shift())
    // right side
    console.log(...matrix.map(arr => arr.pop()))
    // bottom in reverse 
    console.log(...matrix.pop().reverse())
    // left side
    console.log(...matrix.map(arr => arr.shift().reverse())

    unroll(matrix)
}
Enter fullscreen mode Exit fullscreen mode

If we stopped here, we would still have one more problem. An infinite loop. In order for us to stop that from happening, we just need to include a condition that will break the loop when there is no length to our matrix left. Check it out:

function unroll(matrix){
    if(matrix.length === 0) return;

    // top
    console.log(...matrix.shift())
    // right side
    console.log(...matrix.map(arr => arr.pop()))
    // bottom in reverse 
    console.log(...matrix.pop().reverse())
    // left side
    console.log(...matrix.map(arr => arr.shift().reverse())

    unroll(matrix)
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

This is by far the most fun coding challenge I have ever had. I have had my fair share of them, but this one almost felt like a video game! If you liked this blog, hit that follow button!

Also, you should connect with me. 😉
LinkedIn
Twitter
GitHub

Top comments (0)