如何在数组中找到缺失值的索引?

7

I have an array like

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

现在我想使用 indexOf 找到缺失值的索引,即3

8个回答

6
检查值是否为undefined,如下代码所示:
for ( var i = 0; i < a.length; i++ ) {
    if ( typeof a[i] === "undefined" ) {
        // do stuff here or break the loop
    }
}

更新 您也可以这样做:

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

你需要返回i,因为i是当前索引,它将搜索第一个undefined值。
演示:http://jsfiddle.net/vdyypq6o/5/

1
@Thinker:你不能这样做。你需要使用a.indexOf(undefined),但是这并不起作用,因为你的数组在索引3处根本没有任何条目,所以indexOf不会查看它。请参见步骤9(a)和9(b):http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.14 - T.J. Crowder
@Thinker:如果你执行a.indexOf(undefined),它会返回-1。但他需要的是返回i索引。 :) - Radonirina Maminiaina
1
@Thinker:如果你的数组是 a=[1, 2, 3, undefined, 4, 5],那么 indexOf 就可以工作,因为数组在索引 3 处有一个值为 undefined 的条目。但是根据你引用的数组,根本就没有任何条目存在于那里。 - T.J. Crowder
你需要修复你的函数:首先,在函数内部使用全局变量a,其次,你将函数添加到原型中,但没有使用 this,因此得到了 a.indexOfUndefined(a) 而不是仅仅使用 a.indexOfUndefined() 。此外,该函数对于下一个数组 [undefined,1,2,3,,4,5] 返回错误的答案。 - Grundy
2
@RadonirinaMaminiaina,所以你的方法不仅可以找到“缺失”的值,还可以找到“未定义”的值。 - Grundy
显示剩余4条评论

2
很不幸,ES5数组方法需要跳过这样的数组空洞,所以没有indexOf()forEach()可以帮助。ECMAScript 2015有两个新方法叫做find()findIndex()可以帮助你,但是它们目前还没有广泛支持,所以我认为这不是一个好答案。剩下的就是对索引进行迭代了。
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;
}

* — 查看http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.14中的步骤9以了解indexOf(),并查看http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.19中的步骤8以了解需要跳过空洞的map()算法。
** — 当某个索引没有定义值时,在数组中创建一个空洞。因此,从技术上讲,不能说a[3]具有nullundefined值,因为根本没有任何值。但在JavaScript中,当我们尝试获取某个对象的未定义属性时,我们得到的是undefined,这就是为什么a[3] === undefined为真的原因。

2
“顺便说一句,索引3的值是未定义的,而不是空值。”实际上,它根本没有值,因为它不存在。如果存在,其值将为 undefined,即 indexOf(undefined) 将找到它。 - T.J. Crowder
2
@Thinker:不是的,它并没有。你看到的是1)当你检索一个对象的属性(标准数组只是对象)根本不存在(在对象或其原型链中),你会得到undefined。这并不意味着该属性存在;它不存在。这只是属性检索的定义方式。2)==进行类型强制转换,而undefined == nulltrue - T.J. Crowder
这似乎是唯一的答案,可以忽略数组中明确的 undefined 值。+1 - Rick Hitchcock
我认为你可以将条件简化为!a.hasOwnProperty(i),因为如果没有这个属性,元素会自动变成_undefined_。 - Grundy
1
@sainaen,嗯,在没有a[i] === undefined的情况下,速度会慢大约10%。 - Grundy
显示剩余9条评论

0
你可以试试这个。

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


这就是答案下面的“删除”链接的作用。 :-) - T.J. Crowder
我认为,修改后的答案可以满足您的要求。 - Arumoy Roy
我以为你在尝试使用indexOf,所以我也尝试了。这也不是另一个答案的副本,之前我也没有故意复制任何内容。 - Arumoy Roy
如果你要循环遍历数组,使用 indexOf 是没有意义的。(我并不是在尝试做什么;问题提出者正在尝试找到他/她数组中缺失的条目。) - T.J. Crowder
然后,试图定义未定义的东西也是毫无意义的。 - Arumoy Roy
显示剩余2条评论

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

你可以使用each循环来实现这个目的。 可能市场上有更多解决方案:P,但这也是一个不错的选择。你应该试试。


0

这里提供另一种实现你所需功能的方法 -

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

0

使用reduce函数的另一种方式,获取所有缺失的值。

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>


0

假设有两个你知道不在数据中的字符(如英镑符号#和竖杠|),你可以使用这个单行代码:

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

9 是简单的占位符,以防缺失元素在开头或结尾。 (但请注意,在 JavaScript 中,数组末尾的单个额外逗号被忽略,因此无法检查该条件。)

片段

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


-1
创建像这样的数组a=[1,2,3,,4,5];会导致a[3]undefined而不是null
显然a.indexOf(undefined)a.indexOf('undefined')都行不通。将a[3]设置为null也不起作用,因为其后的所有内容都会被左移。
我建议创建自己的数组方法来搜索每个undefined值。
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);
});

它如何帮助找到缺失元素的索引? - Grundy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接