1

I'm using firebase data-base.

After deleting an object, snapshot will return an array with a length longer than the actual array values:

fireBase.ref(REFS_CATEGORIES_ONE_TIMERS).once('value', function (snapshot) {
            const values = snapshot.val(); // This array will contain 2 valus with leanth of 3
            returnFunc(extract);
 });

Array content:

myArray[0] : SomeObject;
myArray[2] : SomeObject;

When looping over this array, it will loop 3 times, on time the value will be undefined.

How can I remove missing entries in an more 'elegant' way than looping over?

MCMatan
  • 8,623
  • 6
  • 46
  • 85
  • I've tried looping and checking in undefined, but I'm looking for a better option – MCMatan Jan 23 '17 at 08:54
  • 1
    voted to reopen - the problem statement is clear – Alnitak Jan 23 '17 at 16:00
  • @MCMatan I've re-edited the question slightly, because there is a very distinct (and important) semantic difference between an "undefined value" as your edited version had written, and a "missing entry". It's possible for `myArray[1]` to actually hold the value `undefined`, but at that point it's no longer strictly missing. – Alnitak Jan 23 '17 at 22:55
  • @Alnitak thanks for your notice – MCMatan Jan 23 '17 at 23:20

3 Answers3

3

The Array.prototype.filter function will only process elements with keys that exist in the array, so calling that with a callback that always returns true will suffice:

var extract = myarray.filter(_ => true);

The resulting array will have contiguous indices, with the missing entries removed and any following entries "collapsed" down into the gap left by them.

Alnitak
  • 334,560
  • 70
  • 407
  • 495
  • Is _ a best practice than () when no argument is needed ? – Ulysse BN Jan 23 '17 at 09:39
  • @UlysseBN I wouldn't argue that it's "best", but it's no worse than using `e => true` whilst ignoring the value of `e`, and uses the common semantic of `_` for an unused variable, and it's also shorter than `() =>`. – Alnitak Jan 23 '17 at 09:57
1

You can use in to test if the index is in the array.

for (var i = 0; i < array.length; i++) {
    if (i in array) {
        // do something with array[i]
    }
}
Barmar
  • 741,623
  • 53
  • 500
  • 612
-1

Below are 3 approaches, I have tried.

var UNDEFINED = undefined;
var UNDEFINED_STR = 'undefined';

var sampleWithOutEmpty = [10, 'hello', null, {}];
var sampleWithEmpty = [, 10, 'hello', , null, {}];

function allAllSlotsFilled (sample){
 /* 
  1.
  check if filtered values that are NOT UNDEFINED is equal to the length of the orignal array ... 
  if the lenghts aren't same then the array EMPTY slots.
 */
 var result = (sample.filter(element => { return typeof(element) !== UNDEFINED_STR;}).length  === sample.length);
 console.log(result);

 /*  
  2.
  sort array in descending order. undefined gets pushed to the last. 
  Then check if the last item is undefined.
  if YES the array has empty slots.
 */
 sample.sort()
 result = (typeof(sample[sample.length -1]) !== UNDEFINED_STR); 
 console.log(result);

 /*
  3.
  Using sets. Create a set with elements in array. Then check is UNDEFINED is a element in set.
  If YES the array has empty slots.
 */
 var set = new Set(sample);
 result = !set.has(UNDEFINED);
 console.log(result);

}

allAllSlotsFilled(sampleWithOutEmpty);
allAllSlotsFilled(sampleWithEmpty);
  • 1
    The OP didn't want to know _if_ the array has missing keys, he wanted a new copy that's contiguous without any missing keys. Also, the code you do have looks for undefined _values_, and not missing keys. There's a semantic difference between `[0,,2]` and `[0, undefined, 2]`. In the latter the key 1 _does exist_, but has an _`undefined`_ value. – Alnitak Jan 23 '17 at 12:27