从Javascript中的数组中删除空元素

IT技术 javascript arrays
2021-01-09 02:26:29

如何从 JavaScript 中的数组中删除空元素?

有没有直接的方法,还是我需要遍历它并手动删除它们?

6个回答

简单的方法:

var arr = [1,2,,3,,-3,null,,0,,undefined,4,,4,,5,,6,,,,];


arr.filter(n => n)
// [1, 2, 3, -3, 4, 4, 5, 6]

arr.filter(Number) 
// [1, 2, 3, -3, 4, 4, 5, 6]

arr.filter(Boolean) 
// [1, 2, 3, -3, 4, 4, 5, 6]

或 - (仅适用于“文本”类型的单个数组项)

['','1','2',3,,'4',,undefined,,,'5'].join('').split(''); 
// output:  ["1","2","3","4","5"]

或 - 经典方式:简单迭代

var arr = [1,2,null, undefined,3,,3,,,0,,,[],,{},,5,,6,,,,],
    len = arr.length, i;

for(i = 0; i < len; i++ )
    arr[i] && arr.push(arr[i]);  // copy non-empty values to the end of the array

arr.splice(0 , len);  // cut the array and leave only the non-empty values

arr // [1,2,3,3,[],Object{},5,6]


通过jQuery:

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

arr = $.grep(arr,function(n){ return n == 0 || n });

arr // [1, 2, 3, 3, 0, 4, 4, 5, 6]


更新 - 只是另一种快速、酷炫的方式(使用 ES6):

var arr = [1,2,null, undefined,3,,3,,,0,,,4,,4,,5,,6,,,,], 
    temp = [];

for(let i of arr)
    i && temp.push(i); // copy each non-empty value to the 'temp' array

arr = temp;

arr // [1, 2, 3, 3, 4, 4, 5, 6]

删除空值

['foo', '',,,'',,null, ' ', 3, true, [], [1], {}, undefined, ()=>{}].filter(String)

// ["foo", null, " ", 3, true, [1], Object {}, undefined, ()=>{}]
ES6 可以做得更简单arr.filter(e=>e),这可以通过 map、reduce 等链接。
2021-03-15 02:26:29
对于纯 javascript,它应该是 arr = arr.filter(function(n){return n; });
2021-03-21 02:26:29
您的纯 JavaScript 代码有一个错误。如果数组中有一个包含“0”的值,该值将被过滤掉,因为“0”是假的。你想要的是: arr.filter(function (n) { return (n !== undefined && n !== null); });
2021-03-31 02:26:29
最早的 IE 对过滤器的支持是 IE9 标准模式。
2021-04-03 02:26:29
foo.join("").split("") 似乎只有当字符串是单个字符时才有效
2021-04-05 02:26:29

编辑:这个问题大约在九年前得到了回答,当时Array.prototype.

现在,当然,我会建议您使用该filter方法。

请记住,此方法将返回一个新数组,其中包含传递您提供给它的回调函数的条件的元素。

例如,如果要删除nullundefined值:

var array = [0, 1, null, 2, "", 3, undefined, 3,,,,,, 4,, 4,, 5,, 6,,,,];

var filtered = array.filter(function (el) {
  return el != null;
});

console.log(filtered);

这将取决于您认为“空”的内容,例如,如果您正在处理字符串,则上述函数不会删除属于空字符串的元素。

我看到经常使用的一种典型模式是除去那些元件falsy,包括一个空字符串""0NaNnullundefined,和false

您可以传递给filter方法、Boolean构造函数,或在过滤条件函数中返回相同的元素,例如:

var filtered = array.filter(Boolean);

或者

var filtered = array.filter(function(el) { return el; });

在两种filter情况下,这都有效,因为第一种情况下方法将Boolean构造函数作为函数调用,转换值,而在第二种情况下,该filter方法在内部将回调的返回值隐式转换为Boolean

如果您正在使用稀疏数组,并且您正在尝试摆脱“漏洞”,则可以使用filter传递返回 true 的回调方法,例如:

var sparseArray = [0, , , 1, , , , , 2, , , , 3],
    cleanArray = sparseArray.filter(function () { return true });

console.log(cleanArray); // [ 0, 1, 2, 3 ]

旧答案:不要这样做!

我使用这种方法,扩展了原生 Array 原型:

Array.prototype.clean = function(deleteValue) {
  for (var i = 0; i < this.length; i++) {
    if (this[i] == deleteValue) {         
      this.splice(i, 1);
      i--;
    }
  }
  return this;
};

test = new Array("", "One", "Two", "", "Three", "", "Four").clean("");
test2 = [1, 2,, 3,, 3,,,,,, 4,, 4,, 5,, 6,,,,];
test2.clean(undefined);

或者您可以简单地将现有元素推送到其他数组中:

// Will remove all falsy values: undefined, null, 0, false, NaN and "" (empty string)
function cleanArray(actual) {
  var newArray = new Array();
  for (var i = 0; i < actual.length; i++) {
    if (actual[i]) {
      newArray.push(actual[i]);
    }
  }
  return newArray;
}

cleanArray([1, 2,, 3,, 3,,,,,, 4,, 4,, 5,, 6,,,,]);
@AlfaTek - 除了最新的浏览器之外,#2 将具有最佳性能,因为 JS 中的数组并不是真正的数组。splice电话是真的对旧的浏览器昂贵,因为它们必须重新编排所有的数组键的收上来的差距。
2021-03-18 02:26:29
如果您无权访问“过滤器”方法,那么您的第一个解决方案非常好。否则,我相信 Alnitak 的答案更好。
2021-03-22 02:26:29
警告:第二个选项将从被视为“假”的数组中删除任何元素,即 false、0、null 和 undefined 的值。这个数组最终会什么都没有:[null,,,0,,0,0,0,false,null,0] 即使我可能想要值为 0 的元素,就像在这个数组中一样:[ 1,0,1,0,0,1]
2021-03-24 02:26:29
我意识到这一点——这就是为什么我只谈到了第二种选择。至于第一个,它的范围太窄了,我会犹豫是否将它作为 Array 原型的一部分。有关更理想的内容,请参阅本页上的 Alnitak 回答。显然,您的确实允许链接。
2021-03-27 02:26:29
@David 不,在现代代码中,您应该安全地扩展Array.prototypeusingObject.defineProperty以使新函数成为不可枚举的属性,然后避免因放入.hasOwnProperty每个循环而导致的性能下降
2021-03-31 02:26:29

如果您需要删除所有空值(""、null、undefined 和 0):

arr = arr.filter(function(e){return e}); 

要删除空值和换行符:

arr = arr.filter(function(e){ return e.replace(/(\r\n|\n|\r)/gm,"")});

例子:

arr = ["hello",0,"",null,undefined,1,100," "]  
arr.filter(function(e){return e});

返回:

["hello", 1, 100, " "]

更新(基于 Alnitak 的评论)

在某些情况下,您可能希望在数组中保留“0”并删除其他任何内容(空、未定义和“”),这是一种方法:

arr.filter(function(e){ return e === 0 || e });

返回:

["hello", 0, 1, 100, " "]
实际上并没有回答被问到的问题。
2021-03-10 02:26:29
或使用var myarr=[1, 2,, 3,, 3,undefined,,"",,0, 4,, 4,, 5,, 6,,,,].filter(Boolean);删除 undefined,"" 和 0
2021-03-19 02:26:29
测试函数可以更明确一点: function(e){return !!e}
2021-04-05 02:26:29
是的,这很好,因为它也删除了 ""。
2021-04-07 02:26:29
@Koen 请注意,这!!e将包括 NaN(与 0 不同),e而不会(如 0)。
2021-04-08 02:26:29

只需一个班轮:

[1, false, "", undefined, 2].filter(Boolean); // [1, 2]

或使用underscorejs.org

_.filter([1, false, "", undefined, 2], Boolean); // [1, 2]
// or even:
_.compact([1, false, "", undefined, 2]); // [1, 2]
@ELLIOTTCABLE 我只是要把这个留在这里,(true).constructor === Boolean然后告诉我我们是否可以用 JS 中的其他内置插件来做到这一点。;)) (当然排除了其他 5 个内置构造函数。(字符串、数组、对象、函数、数字))
2021-03-10 02:26:29
您没有Boolean 视为函数;一个函数。(一个完全正常的函数,除了它是本地实现的。)有人需要对 JavaScript 对象模型做一些研究。;)
2021-03-21 02:26:29
如果您将其Boolean视为函数,它将简单地返回true或者false该值是否为真/假。
2021-04-01 02:26:29
如果数组中的值为 0,则两者都会失败
2021-04-02 02:26:29
这真的很酷——不过我有一个新问题:看起来你正在使用类名作为函数调用——这是类型转换吗?我以前从未见过这个,我不确定我明白为什么传递Boolean作为一个函数工作......
2021-04-04 02:26:29

如果你有 Javascript 1.6 或更高版本,你可以使用Array.filter一个简单的return true回调函数,例如:

arr = arr.filter(function() { return true; });

因为.filter自动跳过原始数组中缺少的元素。

上面链接的 MDN 页面还包含一个很好的错误检查版本filter,可用于不支持正式版本的 JavaScript 解释器。

请注意,这不会删除null条目或具有显式undefined值的条目,但 OP 特别要求“丢失”条目。

你是对的!它可以如此简单(并且有效!):test3 = [1,2,,3,,3,,,,7,,,7,,,0,,,4,,4,,5,, 6,,undefined,,null,,]; printp( "使用数组的原生过滤:", test3.filter( function(value){return (value==undefined) ? 0 : 1;} ) );
2021-03-14 02:26:29
@AlanCN 你完全没有理解我的观点。OP 要求删除丢失的条目,而此处的大部分答案(错误地)删除了任何“虚假”条目。
2021-03-15 02:26:29
要删除未定义或空条目,只需做一个小的修改... arr = arr.filter(function(v) { return v; });
2021-03-27 02:26:29
@katsh 我已经澄清 - 上面的代码确实可以删除根本不存在任何值的条目,这(我随后了解到)在语义上与存在但具有undefined给定值的键的情况不同
2021-04-02 02:26:29
+1正如Alnitak所说,他们有可以在没有js 1.6可用的情况下使用的代码
2021-04-05 02:26:29