Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do arrays with gaps in their indices entail any benefits that compensate their disadvantages

In Javascript arrays may have gaps in their indices, which should not be confused with elements that are simply undefined:

var a = new Array(1), i;
a.push(1, undefined);

for (i = 0; i < a.length; i++) {
  if (i in a) {
    console.log("set with " + a[i]);
  } else {
    console.log("not set");
  }
}

// logs:
// not set
// set with 1
// set with undefined

Since these gaps corrupt the length property I'm not sure, if they should be avoided whenever possible. If so, I would treat them as edge case and not by default:

// default:
function head(xs) {
  return xs[0];
}

// only when necessary:
function gapSafeHead(xs) {
  var i;

  for (i = 0; i < xs.length; i++) {
    if (i in xs) {
      return xs[i];
    }
  }
}

Besides the fact that head is very concise, another advantage is that it can be used on all array-like data types. head is just a single simple example. If such gaps need to be considered throughout the code, the overhead should be significantly.

like image 582
Iven Marquardt Avatar asked Oct 18 '22 18:10

Iven Marquardt


2 Answers

This is likely to come up in any language that overloads hash tables to provide something that colloquially is called an "array". PHP, Lua and JavaScript are three such languages. If you depend on strict sequential numeric array behavior, then it will be an inconvenience for you. More generally, the behavior provides conveniences as well.

Here's a classic algorithm question: to delete a member from the middle of a data structure, which data structure is "better": A linked list or an array?

You're supposed to say "linked list", because deleting a node from a linked list doesn't require you to shift the rest of the array down one index. But linked lists have other pitfalls, so is there another data structure we can use? You can use a sparse array*.

In many languages that provide this hashy type of arrays, removing any arbitrary member of the array will change the length. Unfortunately, JavaScript does not change the length, so you lose out a little there. But nevertheless, the array is "shorter", at least from the Object.keys perspective.

*Many sparse arrays are implemented using linked lists, so don't apply this too generally. In these languages, though, they're hash tables with predictable ordered numeric keys.

like image 53
kojiro Avatar answered Oct 30 '22 19:10

kojiro


Of course, the question is a subjective one, but I argue that the gaps should certainly be avoided, if possible. Arrays are special Javascript objects with very specific purposes. You can totally hack on arrays, manipulate the length property, add properties with keys other than numbers (e.g myArray["foo"] = "bar"), but these mostly devolve into antipatterns. If you need some special form of pseudo-array, you can always just code it yourself with a regular object. After all, typeof [] === "object"

It's not like gaps inherently break your code, but I would avoid pursuing them intentionally.

Does that answer your question?

like image 26
CJ Apel Avatar answered Oct 30 '22 20:10

CJ Apel