-1

Let's suppose I have the following grid and each cell of the grid has an index mapped to a 1d array.

0, 1, 2
3, 4, 5,
6, 7, 8

I could represent this with a 1d array like: [0, 1, 2, 3, 4, 5, 6, 7, 8]

I would like to know a simple way to map a 2d coordinate like (3,1) to its index in the array, in this case, would be 2.

After researching a lot, I found a lot of people suggesting this equation: index = x + (y * width), but it doesn't seem to work in my tests.

For example for (1, 1), the result would be index = 1 + (1 * 3) = 4, and for (3, 1) would be index = 3 + (1 * 3) = 6, which does not make any sense to me.

Is it possible to achieve this in a simple way? Or I would need to use iterators like a for?

3
  • 2
    Do you know that index in js starts with 0? Commented Aug 13, 2019 at 11:49
  • 2
    2D matrix notation is commonly (row, col), with indexes starting at 0. Thus, (3, 1) is invalid (only 3 rows, from 0 to 2). If you start the index at 1, it would be (3, 1) = 6, 3rd row, 1rst column. Commented Aug 13, 2019 at 11:49
  • 3
    you should be using index = x-1 + (y -1* width) Commented Aug 13, 2019 at 11:51

3 Answers 3

5

2D matrix notation is commonly (row, col), with indexes starting at 0.

Thus, (3, 1) is invalid: only 3 rows, from 0 to 2. (1, 1) means 2nd row, 2nd colum, which is 4 in your example. The formula is thus:

(row * width) + col
(2, 1) = 2*3+1 = index 7

once again using 0 for the first row/col.

If you really want to keep thinking with indexes starting at one, just change the formula to:

((row - 1) * width) + (col - 1) = 1D index 
Sign up to request clarification or add additional context in comments.

1 Comment

I do want to note that, while I dislike it, math does often use 1-based indices.
3

In your case it would be index = (x - 1) + ((y - 1) * width) as your coordinate system starts from 1 and arrays start from 0.

let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8];

function getPosition(x, y, width) {
  return x - 1 + (y - 1) * width;
}

console.log({
  position: getPosition(3, 1, 3),
  element: arr[getPosition(3, 1, 3)]
});

Comments

0

It is indeed index = x + y * width (the parens are unnecessary) or index = y + x * width, depending on whether you want your flat array to keep the rows together as in your question ([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], index = x + y * width), or keep columns together ([0, 3, 6, 1, 4, 7, 2, 5, 8], index = y + x * width). But indexes usually start at 0, not 1. So your (1, 1) would be (0, 0) and your (3, 1) would be (2, 0).

Here's the first:

// 0, 1, 2
// 3, 4, 5
// 6, 7, 8
const a = [0, 1, 2, 3, 4, 5, 6, 7, 8];
let x = 0, y = 1;
let index = x + y * 3;
console.log(`(${x}, ${y}) is index ${index}, value ${a[index]}`);
x = 2;
y = 0;
index = x + y * 3;
console.log(`(${x}, ${y}) is index ${index}, value ${a[index]}`);

Here's the second:

// 0, 1, 2
// 3, 4, 5
// 6, 7, 8
const a = [0, 3, 6, 1, 4, 7, 2, 5, 8];
let x = 0, y = 1;
let index = y + x * 3;
console.log(`(${x}, ${y}) is index ${index}, value ${a[index]}`);
x = 2;
y = 0;
index = y + x * 3;
console.log(`(${x}, ${y}) is index ${index}, value ${a[index]}`);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.