網站搜尋

在 Javascript 中從陣列中移除空元素


我如何在 JavaScript 中移除陣列中的空元素?

有沒有一個簡單的方法,還是我需要循環處理並手動移除它們?

答案#1

幾個簡單的方法:

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]

或 - 經典方法:簡單迭代

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
// [1,2,3,3,[],Object{},5,6]

jQuery :

var arr = [1,2,,3,,3,,,0,,,4,,4,,5,,6,,,,];
    
arr = $.grep(arr, n => n == 0 || n);
// [1, 2, 3, 3, 0, 4, 4, 5, 6]

答案#2

編輯: 這個問題幾乎在九年前就已經被回答過了,那時 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);

這將取決於你認為「空」是什麼,例如,如果你正在處理字串,上述函數將不會刪除為空字串的元素。

我經常看到使用的一個典型模式是移除那些 虛值 的元素,這些元素包括空字串 ""、0、NaN、null、undefined 以及 false。

你可以將 Boolean 建構函數傳遞給 filter 方法,或者在篩選條件函數中返回相同的元素,例如:

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,,,,]);

答案#3

如果你需要移除所有空值(""、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, " "]

答案#4

簡單一句話:

[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]

答案#5

如果你有 Javascript 1.6 或更新版本,你可以使用 Array.filter,並搭配一個簡單的 return true 回呼函數,例如:

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

因為 .filter 會自動跳過原始陣列中缺失的元素。

上面連結的 MDN 頁面也包含了一個很好的錯誤檢查版 filter,可以用在不支援官方版本的 JavaScript 直譯器中。

請注意,這不會移除 null 條目,也不會移除具有明確 undefined 值的條目,但原作者特別要求移除「缺失」的條目。

答案#6

要去除洞,您應該使用

arr.filter(() => true)
arr.flat(0) // New in ES2019

用於移除 hole、null 和 undefined:

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

用於移除空洞,以及假值(null、undefined、0、-0、0n、NaN、""、false、document.all)值:

arr.filter(x => x)

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

注意:

  • 空洞是一些沒有元素的陣列索引。
arr = [, ,];
console.log(arr[0], 0 in arr, arr.length); // undefined, false, 2; arr[0] is a hole
arr[42] = 42;
console.log(arr[10], 10 in arr, arr.length); // undefined, false, 43; arr[10] is a hole

arr1 = [1, 2, 3];
arr1[0] = (void 0);
console.log(arr1[0], 0 in arr1); // undefined, true; a[0] is undefined, not a hole

arr2 = [1, 2, 3];
delete arr2[0]; // NEVER do this please
console.log(arr2[0], 0 in arr2, arr2.length); // undefined, false; a[0] is a hole
  • 上述所有方法都會返回給定陣列的副本,而不會就地修改它。
arr = [1, 3, null, 4];
filtered = arr.filter(x => x != null);
console.log(filtered); // [1, 3, 4]
console.log(arr); // [1, 3, null, 4]; not modified

答案#7

乾淨的方法來做這件事。

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

答案#8

實際上,你可以使用 ES6+ 方法,假設陣列如下:

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

而答案可能是以下兩種方式之一:

  • 第一種方法:

    const clearArray = arr.filter(i => i); // [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
    
  • 第二種方法:

    const clearArray = arr.filter(Boolean); // [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
    

2022年10月14日更新:

那兩個答案並不是完全正確,即使在給出的例子中,也是的,它可以運作,但請注意給定陣列中的數字 0,用這兩種方法數字零都消失了,這顯然與使用布林強制轉換來檢查項目有關。

一個完全正確的方法是檢查 nullish 並移除它們:

const notNil = (i) => !(typeof i === 'undefined' || i === null);

const clearArray = arr.filter(i => isNil(i));

const arr = [1,2,3,undefined,4,5,6,undefined,7,8,undefined,undefined,0,9];
const notNil = (i) => !(typeof i === 'undefined' || i === null);

console.log("Not nil: ", arr.filter(notNil));

答案#9

ES6:

let newArr = arr.filter(e => e);

答案#10

簡單的 ES6

['a','b','',,,'w','b'].filter(v => v);

答案#11

使用 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 文件了解 without。

答案#12

如果使用函式庫是一個選項,我知道 underscore.js 有一個名為 compact() 的函式 http://documentcloud.github.com/underscore/ 它還有其他幾個與陣列和集合相關的有用函式。

這裡是他們文件中的一段摘錄:

_.compact(陣列)

返回一個移除所有假值的陣列副本。在 JavaScript 中,false、null、0、""、undefined 和 NaN 都是假值。

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

=> [1, 2, 3]

答案#13

@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 添加的代碼,但我認為 filter 和函數式編程是值得的。

//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;
  };
}

答案#14

既然沒有人提到過,而且大多數人的專案中都有包含 underscore,你也可以使用 _.without(array, *values);。

_.without(["text", "string", null, null, null, "text"], null)
// => ["text", "string", "text"]

答案#15

要從陣列中移除未定義的元素,你可以簡單地使用

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));

答案#16

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

foo.filter(e => e === 0 ? true : e)

回傳

[0, 1, 2, 3, "four"]

如果你確定你的陣列中不會有任何 0,它看起來會更好一些:

foo.filter(e => e)