在Javascript中从数组中删除空元素
-
07-07-2019 - |
题
如何在JavaScript中删除数组中的空元素?
是否有直接的方法,或者我是否需要循环并手动删除它们?
解决方案
编辑:这个问题差不多9年前得到解答,当时Array.prototype
中没有太多有用的内置方法。
现在,我当然建议您使用filter
方法。
请记住,此方法将返回一个新数组,其元素通过您提供给它的回调函数的条件,例如,如果要删除null
或undefined
值:
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 元素,其中包含空字符串""
,0
,NaN
,false
,Boolean
,和<=>。
您可以简单地传递给<=>方法,<=>构造函数,或者只是在过滤条件函数中返回相同的元素,例如:
var filtered = array.filter(Boolean);
或者
var filtered = array.filter(function(el) { return el; });
这两种方式都有效,因为第一种情况下的<=>方法,将<=>构造函数作为函数调用,转换值,在第二种情况下,<=>方法在内部转换返回值隐式回调<=>。
如果您正在使用稀疏数组,并且您正试图摆脱<!>“hole <!>”;您只需使用<=>方法传递返回true的回调,例如:
var sparseArray = [0, , , 1, , , , , 2, , , , 3],
cleanArray = sparseArray.filter(function () { return true });
console.log(cleanArray); // [ 0, 1, 2, 3 ]
旧回答:不要这样做!
我使用此方法,扩展原生数组原型:
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,,,,]);
其他提示
简单方法:
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, ()=>{}]
如果您需要删除所有空值(<!> quot; <!> quot;,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和<!> quot; <!> quot;),这是一种方式:
arr.filter(function(e){ return e === 0 || e });
返回:
["hello", 0, 1, 100, " "]
只需一个班轮:
[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]
如果您使用的是Javascript 1.6或更高版本,则可以使用 Array.filter
使用简单的 return true
回调函数,例如:
arr = arr.filter(function() { return true; });
因为 .filter
会自动跳过原始数组中缺少的元素。
上面链接的MDN页面还包含一个很好的错误检查版本的 filter
,可以在不支持官方版本的JavaScript解释器中使用。
请注意,这不会删除 null
条目,也不会删除具有显式 undefined
值的条目,但OP特别请求“missing”&quot;条目。
要删除孔,您应该使用
arr.filter(() => true)
arr.flat(0) // Currently stage 3, check compatibility before using this
用于删除hole,和falsy(null,undefined,0,-0,NaN,&quot;&quot;,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]
干净利落的方式。
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"]
简单的ES6
['a','b','',,,'w','b'].filter(v => v);
使用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文档。
只需 ES6
和更新的版本方法,假设数组如下:
const arr = [1,2,3,undefined,4,5,6,undefined,7,8,undefined,undefined,0,9];
简单方法:
const clearArray = arr.filter( i => i );
如果使用库是一个选项我知道underscore.js有一个名为compact()的函数 http:// documentcloud.github.com/underscore/ 它还有一些与数组和集合相关的其他有用功能。
以下是他们的文档摘录:
_.compact(array)
返回删除了所有falsy值的数组副本。在JavaScript中,false,null,0,&quot;&quot;,undefined和NaN都是假的。
_.compact([0,1,false,2,'',3]);
=&GT; [1,2,3]
@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添加的代码,但过滤器和功能编程是值得的。
//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;
};
}
由于没有其他人提及它,并且大多数人都在其项目中包含下划线,您也可以使用 _。without(array,* values);
。
_.without(["text", "string", null, null, null, "text"], null)
// => ["text", "string", "text"]
您可能会发现在数组上循环并从要保留的数据中构建一个新数组比通过尝试循环和拼接更容易,因为修改了数组的长度正在循环可以引入问题。
你可以这样做:
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]
你明白了 - 你可以拥有其他类型的过滤功能。可能比你需要的多,但我感觉很慷慨......;)
ES6: let newArr = arr.filter(e => e);
这个怎么样(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"]
您应该使用过滤器来获取没有空元素的数组。 ES6上的示例
const array = [1, 32, 2, undefined, 3];
const newArray = array.filter(arr => arr);
我只是将我的声音添加到上面&#8220;用全局构造函数调用ES5的 Array..filter()
&#8221; golf-hack,但我建议使用 Object
而不是 String
, Boolean
或 Number
,如上所述。
具体来说,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
构造函数的返回值将在任何情况之下,某种对象。与上面提到的primitive-boxing-constructors不同,没有可能的对象值是假的,因此在布尔设置中, 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]
当使用上面最高投票答案时,第一个例子,我得到字符串长度大于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"]
var data = [null, 1,2,3];
var r = data.filter(function(i){ return i != null; })
console.log(r)
[1,2,3]
那是怎么回事:
js> [1,2,,3,,3,,,0,,,4,,4,,5,,6,,,,].filter(String).join(',')
1,2,3,3,0,4,4,5,6
这很有效,我在 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]
*/
另一种方法是利用数组的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 } ) ;
foo = [0, 1, 2, "", , false, 3, "four", null]
foo.filter(function(e) {
return e === 0 ? '0' : e
})
<强>返回强>
[0, 1, 2, 3, "four"]
'误用'for ... in(object-member)循环。 =&GT;只有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);
这可能会对您有所帮助: https://lodash.com/docs/4.17.4#除去
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));
});
};
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
它将从数组中删除空元素并显示其他元素。
使用正则表达式过滤掉无效条目
array = array.filter(/\w/);
filter + regexp
删除空元素的最佳方法是使用 Array.prototype.filter()
,如其他答案中所述。
不幸的是,IE&lt; 9不支持 Array.prototype.filter()
。如果您仍需要支持IE8或更旧版本的IE,您可以使用以下 polyfill 在这些浏览器中添加对 Array.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;
};
}
如果有人想要清理整个数组或对象,这可能有帮助。
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);
<强>输出:强>
删除任何 null
, undefined
,&quot;&quot;
,&quot; &quot;
,空对象
或空数组
jsfiddle 此处