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

1601

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

有没有简单直接的方法,还是必须手动循环并逐个删除?


27
如果你的问题能够明确指出“空元素”指的是什么,那将会很有帮助,因为这里的大部分答案(在我看来)错误地将其解释为“假值”元素。注意:var a = [,,]var a = [undefined, undefined]之间存在区别。前者是真正的空数组,而后者实际上有两个键,但值为undefined - Alnitak
虽然不是完全的答案,但我认为在数组中尽可能避免使用null/undefined是更好的实践。例如,如果你的null来自于使用map函数映射另一个数组时,对于某些元素返回null,那么在运行map之前尝试使用Array.filter过滤掉这些元素。这样可以使你的代码更易读/自我记录。显然,这并不适用于每种情况,但它可以应用于很多情况。 - Luke Redmore
51个回答

0
一个原地解决方案:
function pack(arr) { // remove undefined values
  let p = -1
  for (let i = 0, len = arr.length; i < len; i++) {
    if (arr[i] !== undefined) { if (p >= 0) { arr[p] = arr[i]; p++ } }
    else if (p < 0) p = i
  }
  if (p >= 0) arr.length = p
  return arr
}

let a = [1, 2, 3, undefined, undefined, 4, 5, undefined, null]
console.log(JSON.stringify(a))
pack(a)
console.log(JSON.stringify(a))

-1

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

array = array.filter(/\w/);
filter + regexp

1
这个能工作吗?它显示了一个错误 TypeError: [object RegExp] is not a function - FreeLightman
@FreeLightman 不,它不会。代码毫无意义,甚至不清楚这个代码应该做什么。即使它的目的是检查数组中的每个项是否与正则表达式匹配,这也会过滤掉合法的值,比如 "----"(带有非单词字符的字符串)。 - VLAZ

-1

这是我清理空字段的解决方案。

从费用对象开始: 获取仅可用属性(使用map) 过滤空字段(使用filter) 将结果解析为整数(使用map)

fees.map( ( e ) => e.avail ).filter( v => v!== '').map( i => parseInt( i ) );

这似乎完全不符合问题?1.要求更多的操作 2.似乎针对一些非常特定的数据集 3.甚至不会删除空值。充其量,它只会删除空字符串。 - VLAZ

-1
var a = [{a1: 1, children: [{a1: 2}, undefined, {a1: 3}]}, undefined, {a1: 5}, undefined, {a1: 6}]
function removeNilItemInArray(arr) {
    if (!arr || !arr.length) return;
    for (let i = 0; i < arr.length; i++) {
        if (!arr[i]) {
            arr.splice(i , 1);
            continue;
        }
        removeNilItemInArray(arr[i].children);
    }
}
var b = a;
removeNilItemInArray(a);
// Always keep this memory zone
console.log(b);

-2

这里是一个使用可变行为和ES2015箭头函数表达式的示例:

Array.prototype.clean = function() {
  var args = [].slice.call(arguments);
  return this.filter(item => args.indexOf(item) === -1);
};

// Usage
var arr = ["", undefined, 3, "yes", undefined, undefined, ""];
arr.clean(undefined); // ["", 3, "yes", ""];
arr.clean(undefined, ""); // [3, "yes"];

-2
// recursive implementation
function compact(arr) {
        const compactArray = [];
        //base case 
        if(!arr.length) return []
        if(typeof arr[0] !== "undefined" 
          && arr[0]!==null && arr[0] !== " " && 
          arr[0]!== false &&
          arr[0]!== 0){
          compactArray.push(arr[0]);
        }
        return compactArray.concat(compact(arr.slice(1)))
    }
    
    compact([1,0,false,null,undefined,"banana"])`

-2

很好...非常好 我们也可以像这样替换所有数组值

Array.prototype.ReplaceAllValues = function(OldValue,newValue)
{
    for( var i = 0; i < this.length; i++ )  
    {
        if( this[i] == OldValue )       
        {
            this[i] = newValue;
        }
    }
};

-3
我需要完成相同的任务,并找到了这个线程。最终我使用数组“join”创建一个字符串,使用“_”分隔符,然后进行了一些正则表达式处理:-
1. replace "__" or more with just one "_",
2. replace preceding "_" with nothing "" and similarly 
3. replace and ending "_" with nothing ""

然后使用数组 "split" 来创建一个清理过的数组:

var myArr = new Array("","","a","b","","c","","","","","","","","","e","");
var myStr = "";

myStr = myArr.join("_");

myStr = myStr.replace(new RegExp(/__*/g),"_");
myStr = myStr.replace(new RegExp(/^_/i),"");
myStr = myStr.replace(new RegExp(/_$/i),"");
myArr = myStr.split("_");

alert("myArr=" + myArr.join(","));

...或者在一行代码中实现:

var myArr = new Array("","","a","b","","c","","","","","","","","","e","");

myArr = myArr.join("_").replace(new RegExp(/__*/g),"_").replace(new RegExp(/^_/i),"").replace(new RegExp(/_$/i),"").split("_");

alert("myArr=" + myArr.join(","));

...或者,扩展数组对象 :-

Array.prototype.clean = function() {
  return this.join("_").replace(new RegExp(/__*/g),"_").replace(new RegExp(/^_/i),"").replace(new RegExp(/_$/i),"").split("_");
};

var myArr = new Array("","","a","b","","c","","","","","","","","","e","");

alert("myArr=" + myArr.clean().join(","));

对于字符串类型,这个方法可以正常工作,但是在混合类型的数组中可能会变得“有趣”。 - Jeremy J Starcher

-4

这是另一种方法:

var arr = ["a", "b", undefined, undefined, "e", undefined, "g", undefined, "i", "", "k"]
var cleanArr = arr.join('.').split(/\.+/);

1
这是一个非常糟糕的想法... 如果其中一个值是"a.string.with.dots",那么在创建新数组时它将被分成几个部分... - Tim Baas
你可以自行选择连接/分割的字符,如果你有一个带点的字符串,就不需要使用点。 - Nico Napoli
1
@BogdanGersak 如果在设计时无法保证字符串是否包含或不包含任何特定字符,该怎么办? - Synoli

-5

这样做怎么样?

// Removes all falsy values 
arr = arr.filter(function(array_val) { // creates an anonymous filter func
    var x = Boolean(array_val); // checks if val is null
    return x == true; // returns val to array if not null
  });

1
请解释一下以帮助其他用户。 - DavChana

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