1

Is there any way I can prevent javascript from dropping an error if I try to go into a non existing array index?

Example: array[-1] would return error and eventually break all my code. How can I let it just return 'undefined' and let my script go on? I can implement an if statement before checking the array (so that if the index is minor than zero or major than the array size it would skip it) but this would be very tedious!

this is my code:

if (grid[j-1][i])
n++;
if (grid[j+1][i])
n++;
if (grid[j][i+1])
n++;
if (grid[j][i-1])
n++;
if (grid[j-1][i-1])
n++;
if (grid[j+1][i+1])
n++;
if (grid[j-1][i+1])
n++;
if (grid[j+1][i-1])
n++;

It is inside of two loops which both sees J and I starting from zero. I don't want to change them and neither writing another if statement (as you can see, there are already too much of them!). Is there any solution?

Thanks!

18
  • 1
    You do know you can write all those ifs with one if, right? Commented Apr 22, 2012 at 1:32
  • 1
    @gdoron - I don't think it could (at least not neatly), since more than one rule could apply, and with an if, n would only be incremented once. A loop would work, but then you'd end up with 4 nested loops. Commented Apr 22, 2012 at 1:35
  • 4
    @KarlNicoll how bout n+= !!grid[j-1][i] + !!grid[j+1][i] + ... Commented Apr 22, 2012 at 1:37
  • 1
    @d_inevitable - Nice, but I wouldn't exactly call it "maintainer friendly" :P Commented Apr 22, 2012 at 1:42
  • 2
    @Saturnix !!x "casts" a value to a boolean. It's a double negation. For a single negation see e.g. 11heavens.com/falsy-and-truthy-in-javascript Commented Apr 22, 2012 at 1:46

6 Answers 6

1

If you know the measures of your grid, you can put "sentinel cells" around it.

If you add a -1st index to an array x, it does not count to x.length. Putting an additional last element into the list would increment x.length.

I daresay using sentinel cells combined with the arithmetic counting algorithms mentioned by d_inevitable would be the fastest solution, since it would not involve branches. You even can omit the !! because true will evaluate to 1 and false to 0 in an equalization.

Update:

Do not use index -1. Its an awful lot slower that normal array indexes. See http://jsperf.com/index-1.

Sign up to request clarification or add additional context in comments.

Comments

1

You could use ||, which muffles errors, e.g.:

(grid[j-1] || [])[i] || false

(I haven't tested this, but it should work)

Edit: updated based on am not i am's suggestion

3 Comments

I think the idea is that grid[-1][i] will throw an error because you can't access [i] on undefined. The || won't help with that.
...you'd need to do something more like this... (grid[-1] || [])[i]
Yep, except that you should be able to get rid of the || false, since when the empty array is used, the [i] will give undefined.
0

A less tedious way while still using ifs would be checking the first index if it's defined:

if (typeof grid[j-1] != "undefined" && grid[j-1][i])

Comments

0

You could create a function to do the checks:

function getArrayValue(arr,key) {
    if( key < 0 || key >= arr.length) return null;
    return arr[key];
}

But really you should be avoiding out-of-bounds keys anyway.

Comments

0

I would do this:

for(m = Math.max(j-1,0) ; m <= Math.min(j+1,grid.length-1) ; m++)
  for (p = Math.max(i-1,0) ; p <= Math.min(i+1, grid[m].length-1) ; p++)
     n += !(m == j && p == i) && !!grid[m][p];

3 Comments

Is it your intention to use n as the grid[m] index as well as the main n += ... counter? I'm not understanding it.
@amnotiam, ok it should make sense more now. Thanks for pointing it out.
One more thing, I think you have your min and max reversed.
0

How about this for your solution?

for (dj = -1; dj <= 1; ++dj) {
  for (di = -1; di <= 1; ++di) {
    if ((dj || di) && grid[j+dj] && grid[j+dj][i+di]) {
        n++;
    }
  }
}   

If you refactor all those ifs into a single loop like the above, then having to do the extra conditional is not so bad.

1 Comment

Why was this -1? I see nothing wrong with it. @downvoter: Please explain why MarkReed's answer is wrong.

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.