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.
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.
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.14a.indexOf(undefined), it will return -1. but What he need is, to return the i index. :)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.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.
undefined, indexOf(undefined) would find it.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.without a[i]===undefinedYou 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 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
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);
});