简体   繁体   中英

How to find the index of a missing value in an array?

I have an array like

a=[1,2,3,,4,5];

So now I want to find the missing value index, ie 3 , using indexOf .

Check if the value is undefined like the following code:

for ( var i = 0; i < a.length; i++ ) {
    if ( typeof a[i] === "undefined" ) {
        // do stuff here or break the loop
    }
}

Update You can do this too:

Array.prototype.indexOfUndefined =  function() {
    for ( var i = 0; i < this.length; i++ ) {
        if ( typeof this[i] === "undefined" ) {
            return i;
        }
    }
}

You need to return i because i is the current index, it will search for the first undefined value.

Demo: http://jsfiddle.net/vdyypq6o/5/

Unfortunately, ES5 Array methods are required* to skip such array holes**, so no indexOf() or forEach() will help. ECMAScript 2015 has two new methods called find() and findIndex() that could help you, but they are not widely supported yet , so I assume it's not a good answer for this question.

What's left is a good old iteration over indexes:

function findHole(a) {
    for (var i = 0; i < a.length; i++) {
        // check for only `a[i] === undefined` could be faster,
        // but is not enough as it will cause false positives
        // when array actually contains `undefined` value
        // for example, for `a = [1, undefined, , 2]`,
        // correct implementation should return `2`, not `1`
        if (a[i] === undefined && !a.hasOwnProperty(i)) {
           console.log("Found hole at index " + i);
           return i;
        }
    }
    return -1;
}

* — see step 9 in http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.14 for indexOf() and step 8 http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.19 for map() algorithms that require skipping holes

** — a hole is created in array when there's no value defined for some index, so technically it's not correct to say that a[3] has null or undefined value, because there just isn't any value. But in JavaScript, when we try to get not defined property of some object, what we get is undefined , that why a[3] === undefined is true.

a = [1,2,3,,4,5];
i = 0;
$.each(a , (function(){
  if(a[i]=="") {
    alert(i + ":: yes this is null index");
  }
  i++;
});

you can use the each loop for this purpose. May be there are more solutions for this purpose in market :P but this is also a good one. you should try this.

Just adding another way to achieve what you need -

for ( var i = 0; i < a.length; i++ ) {
    if (!a[i]) {
      console.log("Null index = ",i);
    }
}

You can try this

  a=['1','2','3',,'4'] for(var i=0;i<a.length;i++) { if( a.indexOf(a[i])==-1) // if(typeof a[i] == 'undefined') alert("Index-->"+i) } 

Yet another way with reduce function, getting all missed values.

function findMissed(arr){
    var result = arr.reduce(function(acc,el,index){
        if(index - acc.cur > 1) {
            for(var i=acc.cur+1;i < index;i++){
                acc.res.push(i);
            }
        }
        acc.cur = index;
        return acc;
    },{cur:-1,res:[]});
    var missed = result.res;
    if(result.cur !== arr.length){
      for(var i=result.cur+1;i<arr.length;i++){
          missed.push(i);
      }
    }
    return missed;
}

 function findMissed(arr) { var result = arr.reduce(function(acc, el, index) { if (index - acc.cur > 1) { for (var i = acc.cur + 1; i < index; i++) { acc.res.push(i); } } acc.cur = index; return acc; }, { cur: -1, res: [] }); var missed = result.res; if (result.cur !== arr.length) { for (var i = result.cur + 1; i < arr.length; i++) { missed.push(i); } } return missed; } var a = [1, 2, 3, , 4, 5]; var missed = findMissed(a); printRes(a, missed); console.log(missed) a = [1, , 3, , 5, , 7, , 9] var missed = findMissed(a); console.log(missed) printRes(a, missed); a = [1, ,,,] var missed = findMissed(a); console.log(missed) printRes(a, missed); a = [,,,] var missed = findMissed(a); console.log(missed) printRes(a, missed); a = [,,,2] var missed = findMissed(a); console.log(missed) printRes(a, missed); function printRes(src, res) { document.getElementById('res').innerHTML += JSON.stringify(src) + '<br/>' + JSON.stringify(res) + '<br/>'; } 
 <div id="res"></div> 

Assuming there are two characters that you know aren't in the data (such as a pound sign # and pipe | ), you can use this one-liner:

Math.max(-1, [].concat(9, a, 9).join('#|#').split('|').indexOf('##')-1);

The 9 s are simply placeholders in case the missing element is at the beginning or end. (But note that a single extra comma at the end of an array is ignored in JavaScript, so there's no way to check for that condition.)

Snippet

 console.clear(); //hole at beginning: a= [,1,2,3,4,5]; console.log(Math.max(-1, [].concat(9, a, 9).join('#|#').split('|').indexOf('##')-1)); //0 //hole in middle: a= [1,2,3,,4,5]; console.log(Math.max(-1, [].concat(9, a, 9).join('#|#').split('|').indexOf('##')-1)); //3 //an extra comma at the end of an array is ignored in JavaScript: a= [1,2,3,4,5,]; console.log(Math.max(-1, [].concat(9, a, 9).join('#|#').split('|').indexOf('##')-1)); //-1 //only the last comma is ignored: a= [1,2,3,4,5,,]; console.log(Math.max(-1, [].concat(9, a, 9).join('#|#').split('|').indexOf('##')-1)); //5 

Creating an array like so a=[1,2,3,,4,5]; will cause a[3] to be undefined and not null .

a.indexOf(undefined) or a.indexOf('undefined') will not work for obvious reason. Setting a[3] to null will not work either since everything that follows will be shifted left .

I recommend creating your own array method that will search for every undefined value.

var arr = [1,2,3,,4,5];

Array.prototype.findMissingValues = function(callback){
    for(var i = 0; i < this.length; i++){
        if(typeof this[i] === 'undefined'){

            if(typeof callback != 'undefined'){
                callback.apply(this, [i, this[i]]);
            }
        }
    }
}
arr.findMissingValues(function(index, value){
    alert(value);
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM