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

javascript arrays node.js

764278 观看

30回复

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

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

作者: Tamas Czinege 的来源 发布者: 2019 年 7 月 4 日

回应 (30)


743

决定

编辑:这个问题差不多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);

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

我看到经常使用的一种常见模式是除去那些元件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,,,,]);
作者: CMS 发布者: 11.11.2008 04:12

1258

简单方法:

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]

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

['','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;
delete temp; // discard the variable

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

删除空值

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

// ["foo", null, " ", 3, true, [1], Object {}, undefined, ()=>{}]
作者: vsync 发布者: 16.05.2010 12:02

221

如果需要删除所有空值(“”,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”并删除其他任何内容(null,undefined和“”),这是一种方式:

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

返回:

["hello", 0, 1, 100, " "]
作者: lepe 发布者: 28.10.2011 01:41

129

只需一个班轮:

[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]
作者: andlrc 发布者: 10.12.2012 09:25

117

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

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

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

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

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

作者: Alnitak 发布者: 11.11.2008 04:29

56

要删除孔,您应该使用

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

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

arr.filter(x => x)

删除hole,null和undefined:

arr.filter(x => x != null)

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]

作者: tsh 发布者: 09.01.2018 07:28

52

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

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"]
作者: Tomás Senart 发布者: 26.03.2011 04:57

31

简单的ES6

['a','b','',,,'w','b'].filter(v => v);
作者: ML13 发布者: 22.03.2017 08:24

20

使用Underscore / Lodash:

一般用例:

_.without(array, emptyVal, otherEmptyVal);
_.without([1, 2, 1, 0, 3, 1, 4], 0, 1);

有空的:

_.without(['foo', 'bar', '', 'baz', '', '', 'foobar'], '');
--> ["foo", "bar", "baz", "foobar"]

请参阅lodash文档

作者: c4urself 发布者: 30.11.2012 06:25

16

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

 const arr = [1,2,3,undefined,4,5,6,undefined,7,8,undefined,undefined,0,9];

简单方法:

 const clearArray = arr.filter( i => i );
作者: AmerllicA 发布者: 16.10.2018 06:15

15

如果使用库是一个选项,我知道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]

作者: Luis Perez 发布者: 19.12.2011 06:57

14

@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"]  

这是您需要为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;
  };
}
作者: Erik Johansson 发布者: 18.03.2009 11:54

13

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

_.without(["text", "string", null, null, null, "text"], null)
// => ["text", "string", "text"]
作者: Josh Bedo 发布者: 08.11.2014 06:10

8

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

你可以这样做:

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

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

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]

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

作者: Jason Bunting 发布者: 11.11.2008 04:03

7

ES6: let newArr = arr.filter(e => e);
作者: Kanan Farzali 发布者: 10.07.2018 11:27

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"]
作者: VIJAY P 发布者: 11.12.2015 11:31

6

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

const array = [1, 32, 2, undefined, 3];
const newArray = array.filter(arr => arr);
作者: Gapur Kassym 发布者: 28.12.2017 10:44

3

我简单地增加我的声音上面的“呼叫ES5的Array..filter()具有全球构造”高尔夫黑客,但我建议使用Object,而不是StringBooleanNumber上面建议。

具体来说,ES5 filter()已经不会触发undefined数组中的元素; 所以一个普遍返回的函数true返回所有元素filter()命中,必然只返回非undefined元素:

> [1,,5,6,772,5,24,5,'abc',function(){},1,5,,3].filter(function(){return true})
[1, 5, 6, 772, 5, 24, 5, 'abc', function (){}, 1, 5, 3]

然而,写出...(function(){return true;})比写作更长...(Object); 并且Object任何情况下,构造函数的返回值都是某种对象。与上面提到的原始装箱构造函数不同,没有可能的对象值是假的,因此在布尔设置中,它Object是一个简写function(){return true}

> [1,,5,6,772,5,24,5,'abc',function(){},1,5,,3].filter(Object)
[1, 5, 6, 772, 5, 24, 5, 'abc', function (){}, 1, 5, 3]
作者: ELLIOTTCABLE 发布者: 27.11.2012 03:34

3

当使用上面的最高投票答案时,第一个例子,我得到的字符串长度大于1的单个字符。以下是我对该问题的解决方案。

var stringObject = ["", "some string yay", "", "", "Other string yay"];
stringObject = stringObject.filter(function(n){ return n.length > 0});

如果长度大于0,我们将返回,而不是在未定义时返回,希望能帮助那些人。

返回

["some string yay", "Other string yay"]
作者: John Miller 发布者: 21.10.2014 10:23

3

var data = [null, 1,2,3];
var r = data.filter(function(i){ return i != null; })

console.log(r) 

[1,2,3]

作者: KARTHIKEYAN.A 发布者: 29.03.2017 10:28

2

那个怎么样:

js> [1,2,,3,,3,,,0,,,4,,4,,5,,6,,,,].filter(String).join(',')
1,2,3,3,0,4,4,5,6
作者: JessyNinja 发布者: 12.12.2010 06:20

1

这是有效的,我在AppJet中测试了它(您可以在其IDE上复制粘贴代码并按“重新加载”以查看它是否有效,不需要创建帐户)

/* appjet:version 0.1 */
function Joes_remove(someArray) {
    var newArray = [];
    var element;
    for( element in someArray){
        if(someArray[element]!=undefined ) {
            newArray.push(someArray[element]);
        }
    }
    return newArray;
}

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

print("Original array:", myArray2);
print("Clenased array:", Joes_remove(myArray2) );
/*
Returns: [1,2,3,3,0,4,4,5,6]
*/
作者: Joe Pineda 发布者: 11.11.2008 05:50

1

另一种方法是利用数组的length属性:在数组的“左”包装非空项,然后减少长度。它是一个就地算法 - 不分配内存,对垃圾收集器来说太糟糕了 - 它具有非常好的最佳/平均/最坏情况行为。

与其他人相比,此解决方案在Chrome上的速度提高了2到50倍,在Firefox上提高了5到50倍,如您所见:http//jsperf.com/remove-null-items-from-array

下面的代码将不可枚举的'removeNull'方法添加到Array,它为菊花链返回'this':

var removeNull = function() {
    var nullCount = 0           ;
    var length    = this.length ;
    for (var i=0, len=this.length; i<len; i++) { if (!this[i]) {nullCount++} }
    // no item is null
    if (!nullCount) { return this}
    // all items are null
    if (nullCount == length) { this.length = 0; return this }
    // mix of null // non-null
    var idest=0, isrc=length-1;
    length -= nullCount ;                
    while (true) {
         // find a non null (source) slot on the right
         while (!this[isrc])  { isrc--; nullCount--; } 
         if    (!nullCount) { break }       // break if found all null
         // find one null slot on the left (destination)
         while ( this[idest]) { idest++  }  
         // perform copy
         this[idest]=this[isrc];
         if (!(--nullCount)) {break}
         idest++;  isrc --; 
    }
    this.length=length; 
    return this;
};  

Object.defineProperty(Array.prototype, 'removeNull', 
                { value : removeNull, writable : true, configurable : true } ) ;
作者: GameAlchemist 发布者: 25.05.2013 07:01

1

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

foo.filter(function(e) {
    return e === 0 ? '0' : e
})

回报

[0, 1, 2, 3, "four"]
作者: sqram 发布者: 10.07.2014 07:51

1

'误用'for ... in(object-member)循环。=>只有truthy值出现在循环体中。

// --- Example ----------
var field = [];

field[0] = 'One';
field[1] = 1;
field[3] = true;
field[5] = 43.68;
field[7] = 'theLastElement';
// --- Example ----------

var originalLength;

// Store the length of the array.
originalLength = field.length;

for (var i in field) {
  // Attach the truthy values upon the end of the array. 
  field.push(field[i]);
}

// Delete the original range within the array so that
// only the new elements are preserved.
field.splice(0, originalLength);
作者: michael.zech 发布者: 14.03.2016 12:56

1

这可能对您有所帮助:https//lodash.com/docs/4.17.4#remove

var details = [
            {
                reference: 'ref-1',
                description: 'desc-1',
                price: 1
            }, {
                reference: '',
                description: '',
                price: ''
            }, {
                reference: 'ref-2',
                description: 'desc-2',
                price: 200
            }, {
                reference: 'ref-3',
                description: 'desc-3',
                price: 3
            }, {
                reference: '',
                description: '',
                price: ''
            }
        ];

        scope.removeEmptyDetails(details);
        expect(details.length).toEqual(3);

scope.removeEmptyDetails = function(details){
            _.remove(details, function(detail){
                return (_.isEmpty(detail.reference) && _.isEmpty(detail.description) && _.isEmpty(detail.price));
            });
        };
作者: Sandeep M 发布者: 30.03.2017 05:33

1

var data= { 
    myAction: function(array){
        return array.filter(function(el){
           return (el !== (undefined || null || ''));
        }).join(" ");
    }
}; 
var string = data.myAction(["I", "am","", "working", "", "on","", "nodejs", "" ]);
console.log(string);

输出:

我正在研究nodejs

它将从数组中删除空元素并显示其他元素。

作者: Jitendra virani 发布者: 21.02.2018 06:58

0

使用正则表达式过滤掉无效条目

array = array.filter(/\w/);
filter + regexp
作者: lcabral 发布者: 25.02.2010 11:56

0

删除空元素的最佳方法是使用Array.prototype.filter(),如其他答案中已提到的那样。

不幸的是,Array.prototype.filter()IE <9不支持。如果您仍需要支持IE8或更旧版本的IE,您可以使用以下polyfillArray.prototype.filter()在这些浏览器中添加支持:

if (!Array.prototype.filter) {
  Array.prototype.filter = function(fun/*, thisArg*/) {
    'use strict';
    if (this === void 0 || this === null) {
      throw new TypeError();
    }
    var t = Object(this);
    var len = t.length >>> 0;
    if (typeof fun !== 'function') {
      throw new TypeError();
    }
    var res = [];
    var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
    for (var i = 0; i < len; i++) {
      if (i in t) {
        var val = t[i];
        if (fun.call(thisArg, val, i, t)) {
          res.push(val);
        }
      }
    }
    return res;
  };
}
作者: John Slegers 发布者: 11.03.2016 06:26

0

如果有人正在寻找清理整个数组或对象,这可能会有所帮助

var qwerty = {
    test1: null,
    test2: 'somestring',
    test3: 3,
    test4: {},
    test5: {
        foo: "bar"
    },
    test6: "",
    test7: undefined,
    test8: " ",
    test9: true,
    test10: [],
    test11: ["77","88"],
    test12: {
        foo: "foo",
        bar: {
            foo: "q",
            bar: {
                foo:4,
                bar:{}
            }
        },
        bob: {}
    }
}

var asdfg = [,,"", " ", "yyyy", 78, null, undefined,true, {}, {x:6}, [], [2,3,5]];

function clean_data(obj) {
    for (var key in obj) {
        // Delete null, undefined, "", " "
        if (obj[key] === null || obj[key] === undefined || obj[key] === "" || obj[key] === " ") {
            delete obj[key];
        }
        // Delete empty object
        // Note : typeof Array is also object
        if (typeof obj[key] === 'object' && Object.keys(obj[key]).length <= 0) {
            delete obj[key];
        }
        // If non empty object call function again
        if(typeof obj[key] === 'object'){
            clean_data(obj[key]);
        }
    }
    return obj;
}

var objData = clean_data(qwerty);
console.log(objData);
var arrayData = clean_data(asdfg);
console.log(arrayData);

输出:

删除任何是nullundefined""" "empty object或者empty array

jsfiddle 在这里

作者: Puni 发布者: 24.11.2016 10:30
32x32