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

Tam*_*ege 1006 javascript arrays node.js

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

有一种简单的方法,还是我需要循环并手动删除它们?

vsy*_*ync 1318

简单方法:

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]
Run Code Online (Sandbox Code Playgroud)

或 - (仅适用于"text"类型的单个数组项)

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

或 - 经典方式:简单迭代

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]
Run Code Online (Sandbox Code Playgroud)


通过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]
Run Code Online (Sandbox Code Playgroud)


更新 - 只是另一种快速,酷的方式(使用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]
Run Code Online (Sandbox Code Playgroud)

删除空值

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

// ["foo", null, " ", 3, true, [1], Object {}, undefined, ()=>{}]
Run Code Online (Sandbox Code Playgroud)

  • 最早的IE支持过滤器是IE9标准模式. (34认同)
  • 如果字符串是单个字符,`foo.join("").split("")`似乎只能工作 (17认同)
  • note - 过滤器是在javascript 1.6中引入的 (15认同)
  • 对于纯JavaScript,它应该是`arr = arr.filter(function(n){return n;});` (12认同)
  • 您的纯JavaScript代码有一个错误.如果数组中的值为"0",则该值将被过滤掉,因为"0"是假的.你想要的是:arr.filter(function(n){return(n!== undefined && n!== null);}); (7认同)
  • ES6可以做得更简单``arr.filter(e => e)`,这可以通过map,reduce等链接. (4认同)
  • 有几个人指出,`arr.filter(n => n)`和它的es5等价物将删除虚假值,这可能是不可取的.但是,过滤器与其他数组方法一样,只会迭代定义的值.因此`filter(n => true)`是一种很好的简洁方法来压缩稀疏数组. (2认同)

CMS*_*CMS 874

编辑:这个问题差不多9年前回答,当时没有太多有用的内置方法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);
Run Code Online (Sandbox Code Playgroud)

它取决于你认为是"空"的,例如,如果你处理字符串,上面的函数不会删除空字符串的元素.

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

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

var filtered = array.filter(Boolean);
Run Code Online (Sandbox Code Playgroud)

要么

var filtered = array.filter(function(el) { return el; });
Run Code Online (Sandbox Code Playgroud)

在这两种方式中,这都有效,因为第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 ]
Run Code Online (Sandbox Code Playgroud)

老答案:不要这样做!

我使用这个方法,扩展了原生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);
Run Code Online (Sandbox Code Playgroud)

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

// 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,,,,]);
Run Code Online (Sandbox Code Playgroud)

  • 警告:第二个选项将从被视为"falsy"的数组中删除任何元素,即false,0,null和undefined的值.这个数组最终什么都没有:[null ,,, 0 ,, 0,0,0,false,null,0]即使我可能想要值为0的元素,就像在这个数组中一样:[ 1,0,1,0,0,1] (103认同)
  • 我意识到 - 这就是为什么我只谈到第二种选择.至于第一个,它的范围非常狭窄,我会毫不犹豫地将它作为Array原型的一部分.请参阅Alnitak在此页面上的答案,了解更为理想的内容.显然,你的确允许链接. (5认同)
  • @AlfaTek - 除了最新的浏览器#2之外,所有浏览器都具有最佳性能,因为JS中的数组并不是真正的数组.`splice`调用在旧浏览器上是非常昂贵的,因为它们必须重新编号所有数组键以缩小差距. (2认同)

lep*_*epe 232

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

arr = arr.filter(function(e){return e}); 
Run Code Online (Sandbox Code Playgroud)

要删除空值和换行符:

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

例:

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

返回:

["hello", 1, 100, " "]
Run Code Online (Sandbox Code Playgroud)

更新(根据Alnitak的评论)

在某些情况下,您可能希望在数组中保留"0"并删除其他任何内容(null,undefined和""),这是一种方式:

arr.filter(function(e){ return e === 0 || e });
Run Code Online (Sandbox Code Playgroud)

返回:

["hello", 0, 1, 100, " "]
Run Code Online (Sandbox Code Playgroud)

  • @Koen请注意,`!! e`将包含NaN(与0不同),其中`e`不会(如0). (4认同)
  • 测试函数可能更明确一点:`function(e){return !! e}` (3认同)
  • 或者使用`var myarr = [1,2 ,, 3 ,, 3,undefined ,,"",, 0,4,4,5,5 ,,,,,].过滤(布尔);`删除undefined ,""和0 (2认同)

and*_*lrc 132

只需一个班轮:

[1, false, "", undefined, 2].filter(Boolean); // [1, 2]
Run Code Online (Sandbox Code Playgroud)

或使用underscorejs.org:

_.filter([1, false, "", undefined, 2], Boolean); // [1, 2]
// or even:
_.compact([1, false, "", undefined, 2]); // [1, 2]
Run Code Online (Sandbox Code Playgroud)

  • 如果你将`Boolean`视为一个函数,它将简单地返回'true`或`false`,这个值是真正的/ falsy. (8认同)
  • 你不是*把*布尔作为一个函数; 它*是一个功能.(一个完全正常的函数,除了它是本机实现的.)有人需要对JavaScript对象模型进行一些研究.;) (7认同)

Aln*_*tak 123

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

arr = arr.filter(function() { return true; });
Run Code Online (Sandbox Code Playgroud)

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

上面链接的MDN页面还包含一个很好的错误检查版本filter,可以在不支持官方版本的JavaScript解释器中使用.

请注意,这不会删除null具有显式undefined值的条目或条目,但OP特别请求"缺少"条目.

  • 要删除未定义或空条目,只需进行一些小修改... arr = arr.filter(function(v){return v;}); (4认同)
  • @katsh我已经澄清了 - 上面的代码_does_工作来删除根本没有值存在的条目,这(我后来)学到的语义与存在的键的情况有所不同,但是它的'undefined'为给定的价值. (3认同)
  • Array.filter是ES5,适用于IE9及更高版本. (3认同)
  • @AlanCN你完全错过了我的观点.OP要求删除_missing_条目,而这里的大部分答案(错误地)删除任何"虚假"条目. (3认同)
  • +1正如Alnitak所说,他们拥有可以在没有js 1.6的情况下使用的代码 (2认同)

tsh*_*tsh 60

要删除孔,您应该使用

arr.filter(() => true)
arr.flat(0) // Currently stage 3, check compatibility before using this
Run Code Online (Sandbox Code Playgroud)

用于删除hole,和falsy(null,undefined,0,-0,NaN,"",false,document.all)值:

arr.filter(x => x)
Run Code Online (Sandbox Code Playgroud)

删除hole,null和undefined:

arr.filter(x => x != null)
Run Code Online (Sandbox Code Playgroud)

arr = [, null, (void 0), 0, -0, NaN, false, '', 42];
console.log(arr.filter(() => true)); // [null, (void 0), 0, -0, NaN, false, '', 42]
console.log(arr.filter(x => x)); // [42]
console.log(arr.filter(x => x != null)); // [0, -0, NaN, false, "", 42]
Run Code Online (Sandbox Code Playgroud)

  • 这应该是答案中的高位.你能用孔/孔扩展你的意思吗? (3认同)
  • @samayo孔是未填充的数组项,即`[,,]` (2认同)

Tom*_*art 54

干净的方式来做到这一点.

var arr = [0,1,2,"Thomas","false",false,true,null,3,4,undefined,5,"end"];
arr = arr.filter(Boolean);
// [1, 2, "Thomas", "false", true, 3, 4, 5, "end"]
Run Code Online (Sandbox Code Playgroud)

  • 空元素是'undefined`; 这基本上删除了所有的虚假值. (5认同)

小智 34

简单的ES6

['a','b','',,,'w','b'].filter(v => v);
Run Code Online (Sandbox Code Playgroud)

  • 这不起作用:`[1, 'two', null, undefined, , NaN, false, true, 0].filter(v =&gt; v)`。 (2认同)

c4u*_*elf 22

使用Underscore/Lodash:

一般用例:

_.without(array, emptyVal, otherEmptyVal);
_.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
Run Code Online (Sandbox Code Playgroud)

有空的:

_.without(['foo', 'bar', '', 'baz', '', '', 'foobar'], '');
--> ["foo", "bar", "baz", "foobar"]
Run Code Online (Sandbox Code Playgroud)

请参阅lodash文档.

  • 您实际上可能想要使用[#compact](https://lodash.com/docs#compact) (9认同)

Ame*_*icA 20

只是ES6和更新的版本方法,假设数组如下:

 const arr = [1,2,3,undefined,4,5,6,undefined,7,8,undefined,undefined,0,9];
Run Code Online (Sandbox Code Playgroud)

简单方法:

 const clearArray = arr.filter( i => i );
Run Code Online (Sandbox Code Playgroud)


Lui*_*rez 16

如果使用库是一个选项,我知道underscore.js有一个名为compact()的函数http://documentcloud.github.com/underscore/它还有一些与数组和集合相关的其他有用函数.

以下是他们的文档摘录:

_.compact(数组)

返回删除了所有falsy值的数组副本.在JavaScript中,false,null,0,"",undefined和NaN都是假的.

_.compact([0,1,false,2,'',3]);

=> [1,2,3]


Eri*_*son 15

@Alnitak

实际上,如果添加一些额外的代码,Array.filter适用于所有浏览器.见下文.

var array = ["","one",0,"",null,0,1,2,4,"two"];

function isempty(x){
if(x!=="")
    return true;
}
var res = array.filter(isempty);
document.writeln(res.toJSONString());
// gives: ["one",0,null,0,1,2,4,"two"]  
Run Code Online (Sandbox Code Playgroud)

这是您需要为IE添加的代码,但过滤器和功能编程的价值是imo.

//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.filter)
{
  Array.prototype.filter = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var res = new Array();
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
      {
        var val = this[i]; // in case fun mutates this
        if (fun.call(thisp, val, i, this))
          res.push(val);
      }
    }

    return res;
  };
}
Run Code Online (Sandbox Code Playgroud)

  • @Tony 不,不应该,因为其中包含空字符串的元素与“空元素”不同,后者是 OP 所要求的。 (2认同)

Jos*_*edo 14

由于没有其他人提及它,并且大多数人都有下划线包含在他们的项目中,你也可以使用_.without(array, *values);.

_.without(["text", "string", null, null, null, "text"], null)
// => ["text", "string", "text"]
Run Code Online (Sandbox Code Playgroud)


use*_*281 13

要从数组中删除未定义的元素,您可以简单地使用

const array = [
  { name: "tim", age: 1 },
  undefined,
  { name: "ewrfer", age: 22 },
  { name: "3tf5gh", age: 56 },
  null,
  { name: "kygm", age: 19 },
  undefined,
];
console.log(array.filter(Boolean));
Run Code Online (Sandbox Code Playgroud)


sqr*_*ram 11

foo = [0, 1, 2, "", , false, 3, "four", null]

foo.filter(e => e === 0 ? true : e)
Run Code Online (Sandbox Code Playgroud)

回报

[0, 1, 2, 3, "four"]
Run Code Online (Sandbox Code Playgroud)

如果你确信数组中不会有任何 0,它看起来会更好一些:

foo.filter(e => e)
Run Code Online (Sandbox Code Playgroud)


Kan*_*ali 10

ES6: let newArr = arr.filter(e => e);
Run Code Online (Sandbox Code Playgroud)


Jas*_*ing 8

您可能会发现在数组上循环并从要保留的数据中构建一个新数组比通过尝试循环和拼接更容易,因为在循环时修改数组的长度过来会引入问题.

你可以这样做:

function removeFalsyElementsFromArray(someArray) {
    var newArray = [];
    for(var index = 0; index < someArray.length; index++) {
        if(someArray[index]) {
            newArray.push(someArray[index]);
        }
    }
    return newArray;
}
Run Code Online (Sandbox Code Playgroud)

实际上这是一个更通用的解决方案:

function removeElementsFromArray(someArray, filter) {
    var newArray = [];
    for(var index = 0; index < someArray.length; index++) {
        if(filter(someArray[index]) == false) {
            newArray.push(someArray[index]);
        }
    }
    return newArray;
}

// then provide one or more filter functions that will 
// filter out the elements based on some condition:
function isNullOrUndefined(item) {
    return (item == null || typeof(item) == "undefined");
}

// then call the function like this:
var myArray = [1,2,,3,,3,,,,,,4,,4,,5,,6,,,,];
var results = removeElementsFromArray(myArray, isNullOrUndefined);

// results == [1,2,3,3,4,4,5,6]
Run Code Online (Sandbox Code Playgroud)

你明白了 - 你可以拥有其他类型的过滤功能.可能比你需要的多,但我感觉很慷慨...;)


VIJ*_*Y P 6

这个怎么样(ES6):从数组中删除Falsy值.

var arr = [0,1,2,"test","false",false,true,null,3,4,undefined,5,"end"];

arr.filter((v) => (!!(v)==true));

//output:

//[1, 2, "test", "false", true, 3, 4, 5, "end"]
Run Code Online (Sandbox Code Playgroud)


Gap*_*sym 6

您应该使用filter来获取没有空元素的数组.ES6上的示例

const array = [1, 32, 2, undefined, 3];
const newArray = array.filter(arr => arr);
Run Code Online (Sandbox Code Playgroud)