1

I am trying to rotate the image (a) by making the values at "a" coordinates map to the rotated image according to the coordinates listed below. Why does this not work?

a = [[1, 2, 3],
     [4, 5, 6],
     [7, 8, 9]]

// Desired result: 
//  rotateImage(a) =
//     [[7, 4, 1],
//      [8, 5, 2],
//      [9, 6, 3]]

// aCoords =  [[00,01,02],
//             [10, 11, 12],
//             [20,21,22]]

// rotatedImageCoordsRelatingToa = [[20, 10, 00],
//                                     [21, 11, 01],
//                                     [22,12,02]]

function rotateImage(a) {
const image = [...a]
const length = a.length
const rotatedImage = [...a]
for(let i=0;i<length;i++){
    for(let j=0;j<length;j++){
        let toRotateCoord = length-(1+j)
        console.log("Original coordinates:" + i,j + " should map to rotated coordinates:"+ toRotateCoord, i)
        rotatedImage[i][j] = image[toRotateCoord][i]
    }
}
return rotatedImage;
}

rotateImage(a);

When I run this I get

//[[7,4,7], 
// [8,5,4], 
// [9,4,7]]
// Not
//     [[7, 4, 1],
//      [8, 5, 2],
//      [9, 6, 3]]

I know there is probably a better algorithm for this but I am curious why this approach is not working. It seems to be something with how the arrays are being accessed.

2
  • 1
    I don't know JS, but judging by your output, it looks to me that rotatedImage and image might point to the same memory. Commented Apr 29, 2020 at 18:52
  • looks like more like this question: stackoverflow.com/q/60508865/1447675 Commented Apr 29, 2020 at 20:50

2 Answers 2

3

As Cris Luengo mentioned, it appears that using the spread operator to assign rotatedImage still points to the same location in memory. I added a for loop to create the new array and now it works:

a = [[1, 2, 3],
     [4, 5, 6],
     [7, 8, 9]]

rotateImage(a);

function rotateImage(a) {
const image = [...a]
const length = a.length
const rotatedImage = []

for(var i = 0; i < length; i++){
        rotatedImage.push([]);
    };

for(let i=0;i<length;i++){
    for(let j=0;j<length;j++){
        let toRotateCoord = length-(1+j)
        rotatedImage[i][j] = image[toRotateCoord][i]
    }
}
return rotatedImage;
}
Sign up to request clarification or add additional context in comments.

1 Comment

AFAIK, objects are always referenced. Spread operator does not change that behaviour.
2

The problem is that although rotatedImage = [...a] creates a new array, it does not create new subarrays. So, rotatedImage shares its rows with image. Whatever you assign to rotatedImage[i][j] will mutate the rows in image, affecting the result of some of the next assignments.

To avoid this, initialise rotatedImage as:

const rotatedImage = Array.from({length}, _ => []);

... and your code will work.

BTW: you don't need the image variable. Since you don't intend to mutate it, you can just use a.

function rotateImage(a) {
    const length = a.length;
    const rotatedImage = Array.from({length}, _ => []);
    for (let i = 0; i < length; i++) {
        for (let j = 0; j < length; j++) {
            rotatedImage[i][j] = a[length - (1 + j)][i];
        }
    }
    return rotatedImage;
}

let a = [[1, 2, 3],
         [4, 5, 6],
         [7, 8, 9]];
let b = rotateImage(a);
for (let row of b) console.log(row+"")

1 Comment

Great, thanks for the follow up, this makes a lot of sense. It was strangely difficult to find a definitive answer on how to copy an array without pointing to it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.