7

I have an array like

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

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

8 Answers 8

6

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/

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

9 Comments

Thanks dude. We know this way but i want to find using indexOf method
@Thinker: You can't. You'd want a.indexOf(undefined), but that doesn't work, because your array doesn't have any entry at all at index 3, and so indexOf doesn't look at it. See steps 9(a) and 9(b): ecma-international.org/ecma-262/5.1/#sec-15.4.4.14
@Thinker: if you do a.indexOf(undefined), it will return -1. but What he need is, to return the i index. :)
@Thinker: If your array were a=[1, 2, 3, undefined, 4, 5], then indexOf would work, because the array would have an entry at index 3 with the value undefined. But with the array as you've quoted it, there's no entry there at all.
@RadonirinaMaminiaina, so, your method find not only missed value, but undefined values too
|
2

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.

14 Comments

"btw, index 3 has undefined value, not null" Actually, it doesn't have a value at all, because it's not there. If it were there, with the value undefined, indexOf(undefined) would find it.
Actually index 3 has a value. Its both null and undefined. See the link: jsfiddle.net/x6npohz6/1
@Thinker: No, it doesn't. What you're seeing there is 1) When you retrieve a property of an object (and standard arrays are just objects) that doesn't exist at all (on the object or in its prototype chain), you get back undefined. That doesn't mean the property exists; it doesn't. It's just how property retrieval is defined. 2) == does type coercion, and undefined == null is true.
@Thinker try use '===' instead '=='
@sainaen, eh, ~10% slowly from case without a[i]===undefined
|
0
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.

Comments

0

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);
    }
}

Comments

0

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)
              }

7 Comments

Lol seriously ? This is similar to the upvoted answer of Radonirina which was provided 10 minutes ago...
Yah I realised after posting.
That's what the "delete" link under the answer is for. :-)
I think, the changed answer can fullfill your requirement.
I thought you are trying to use indexOf, thats why I tried. It is also not any copy of another answer. and previously I did not copy anything intentionally.
|
0

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>

Comments

0

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 9s 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

Comments

-1

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);
});

1 Comment

how it can help find index for missed element?

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.