arrays javascript刪除陣列元素 - 如何從JavaScript中刪除數組中的特定元素?



splice用法 javascript陣列 (25)

我有一個整數數組,我正在使用.push()方法向其中添加元素。

有沒有一種簡單的方法從數組中刪除特定元素? 相當於像array.remove(int);

我必須使用核心 JavaScript - 不允許使用框架。


Answers

你可以使用lodash _.pull (變異數組), _.pullAt (變異數組)或_.without (不變異數組),

var array1 = ['a', 'b', 'c', 'd']
_.pull(array1, 'c')
console.log(array1) // ['a', 'b', 'd']

var array2 = ['e', 'f', 'g', 'h']
_.pullAt(array2, 0)
console.log(array2) // ['f', 'g', 'h']

var array3 = ['i', 'j', 'k', 'l']
var newArray = _.without(array3, 'i') // ['j', 'k', 'l']
console.log(array3) // ['i', 'j', 'k', 'l']

我不知道你期望array.remove(int)如何表現。 我可以想到你可能想要的三種可能性。

要在索引i處刪除數組的元素:

array.splice(i, 1);

如果要從數組中刪除具有值number每個元素:

for(var i = array.length - 1; i >= 0; i--) {
    if(array[i] === number) {
       array.splice(i, 1);
    }
}

如果您只想使索引i處的元素不再存在,但您不希望其他元素的索引發生更改:

delete array[i];

我還有另一個從數組中刪除的好方法:

var words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];

const result = words.filter(word => word.length > 6);

console.log(result);
// expected output: Array ["exuberant", "destruction", "present"]

filter


ES6和無突變:( 2016年10月)

const removeByIndex = (list, index) =>
  [
    ...list.slice(0, index),
    ...list.slice(index + 1)
  ];

然後 :

removeByIndex([33,22,11,44],1) //=> [33,11,44]

編輯於2016年10月

在這個代碼示例中,我使用“array.filter(...)”函數從數組中刪除不需要的項,此函數不會更改原始數組並創建新數組。 如果您的瀏覽器不支持此功能(例如版本9之前的IE或版本1.5之前的Firefox),請考慮使用Mozilla中的過濾器polyfill

刪除項目(ECMA-262 Edition 5 code aka oldstyle JS)

var value = 3

var arr = [1, 2, 3, 4, 5, 3]

arr = arr.filter(function(item) { 
    return item !== value
})

console.log(arr)
// [ 1, 2, 4, 5 ]

刪除項目(ES2015代碼)

let value = 3

let arr = [1, 2, 3, 4, 5, 3]

arr = arr.filter(item => item !== value)

console.log(arr)
// [ 1, 2, 4, 5 ]

重要事項 ES2015“()=> {}”IE中根本不支持箭頭功能語法,Chrome版本為45版本,Firefox版本為22版本,Safari版本為10版本。 要在舊瀏覽器中使用ES2015語法,您可以使用BabelJS

刪除多個項目(ES2016代碼)

此方法的另一個優點是您可以刪除多個項目

let forDeletion = [2, 3, 5]

let arr = [1, 2, 3, 4, 5, 3]

arr = arr.filter(item => !forDeletion.includes(item))
// !!! Read below about array.includes(...) support !!!

console.log(arr)
// [ 1, 4 ]

重要信息 IE中根本不支持“array.includes(...)”功能,47版本之前的Chrome版本,43版本之前的Firefox版本,9版本之前的Safari版本以及14版本之前的Edge版本所以這裡是來自Mozilla的polyfill

刪除多個項目(尖端實驗性JavaScript ES2018?)

// array-lib.js

export function remove(...forDeletion) {
    return this.filter(item => !forDeletion.includes(item))
}

// main.js

import { remove } from './array-lib.js'

let arr = [1, 2, 3, 4, 5, 3]

// :: This-Binding Syntax Proposal
// using "remove" function as "virtual method"
// without extending Array.prototype
arr = arr::remove(2, 3, 5)

console.log(arr)
// [ 1, 4 ]

在BabelJS中自己嘗試:)

參考


更新:僅當您不能使用ECMAScript 2015(以前稱為ES6)時,才建議使用此方法。 如果你可以使用它,這裡的其他答案提供了更簡潔的實現。

這裡的要點將解決您的問題,並刪除所有出現的參數而不只是1(或指定的值)。

Array.prototype.destroy = function(obj){
    // Return null if no objects were found and removed
    var destroyed = null;

    for(var i = 0; i < this.length; i++){

        // Use while-loop to find adjacent equal objects
        while(this[i] === obj){

            // Remove this[i] and store it within destroyed
            destroyed = this.splice(i, 1)[0];
        }
    }

    return destroyed;
}

用法:

var x = [1, 2, 3, 3, true, false, undefined, false];

x.destroy(3);         // => 3
x.destroy(false);     // => false
x;                    // => [1, 2, true, undefined]

x.destroy(true);      // => true
x.destroy(undefined); // => undefined
x;                    // => [1, 2]

x.destroy(3);         // => null
x;                    // => [1, 2]

如果陣列中有復雜對象,可以使用過濾器嗎? 在$ .inArray或array.splice不那麼容易使用的情況下。 特別是如果對像在數組中可能很淺。

例如,如果您有一個帶有Id字段的對象,並且您希望從數組中刪除該對象:

this.array = this.array.filter(function(element, i) {
    return element.id !== idToRemove;
});

Array.prototype.remByVal = function(val) {
    for (var i = 0; i < this.length; i++) {
        if (this[i] === val) {
            this.splice(i, 1);
            i--;
        }
    }
    return this;
}
//Call like
[1, 2, 3, 4].remByVal(3);

Array.prototype.remByVal = function(val) {
    for (var i = 0; i < this.length; i++) {
        if (this[i] === val) {
            this.splice(i, 1);
            i--;
        }
    }
    return this;
}

var rooms = ['hello', 'something']

rooms = rooms.remByVal('hello')

console.log(rooms)


我知道已有很多答案,但其中許多似乎使問題複雜化。這是一種刪除鍵的所有實例的簡單遞歸方法 - 調用self直到找不到索引。是的,它只能在瀏覽器中使用indexOf,但它很簡單,可以很容易地填充。

獨立功能

function removeAll(array, key){
    var index = array.indexOf(key);

    if(index === -1) return;

    array.splice(index, 1);
    removeAll(array,key);
}

原型方法

Array.prototype.removeAll = function(key){
    var index = this.indexOf(key);

    if(index === -1) return;

    this.splice(index, 1);
    this.removeAll(key);
}

基於所有主要正確的答案並考慮到建議的最佳實踐(特別是不直接使用Array.prototype),我想出了以下代碼:

function arrayWithout(arr, values) {
  var isArray = function(canBeArray) {
    if (Array.isArray) {
      return Array.isArray(canBeArray);
    }
    return Object.prototype.toString.call(canBeArray) === '[object Array]';
  };

  var excludedValues = (isArray(values)) ? values : [].slice.call(arguments, 1);
  var arrCopy = arr.slice(0);

  for (var i = arrCopy.length - 1; i >= 0; i--) {
    if (excludedValues.indexOf(arrCopy[i]) > -1) {
      arrCopy.splice(i, 1);
    }
  }

  return arrCopy;
}

回顧上述功能,儘管它工作正常,但我意識到可能會有一些性能提升。使用ES6而不是ES5也是一種更好的方法。為此,這是改進的代碼:

const arrayWithoutFastest = (() => {
  const isArray = canBeArray => ('isArray' in Array) 
    ? Array.isArray(canBeArray) 
    : Object.prototype.toString.call(canBeArray) === '[object Array]';

  let mapIncludes = (map, key) => map.has(key);
  let objectIncludes = (obj, key) => key in obj;
  let includes;

  function arrayWithoutFastest(arr, ...thisArgs) {
    let withoutValues = isArray(thisArgs[0]) ? thisArgs[0] : thisArgs;

    if (typeof Map !== 'undefined') {
      withoutValues = withoutValues.reduce((map, value) => map.set(value, value), new Map());
      includes = mapIncludes;
    } else {
      withoutValues = withoutValues.reduce((map, value) => { map[value] = value; return map; } , {}); 
      includes = objectIncludes;
    }

    const arrCopy = [];
    const length = arr.length;

    for (let i = 0; i < length; i++) {
      // If value is not in exclude list
      if (!includes(withoutValues, arr[i])) {
        arrCopy.push(arr[i]);
      }
    }

    return arrCopy;
  }

  return arrayWithoutFastest;  
})();

如何使用:

const arr = [1,2,3,4,5,"name", false];

arrayWithoutFastest(arr, 1); // will return array [2,3,4,5,"name", false]
arrayWithoutFastest(arr, 'name'); // will return [2,3,4,5, false]
arrayWithoutFastest(arr, false); // will return [2,3,4,5]
arrayWithoutFastest(arr,[1,2]); // will return [3,4,5,"name", false];
arrayWithoutFastest(arr, {bar: "foo"}); // will return the same array (new copy)

我目前正在撰寫一篇博文,其中我對Array的幾個解決方案進行了基準測試,沒有遇到任何問題,並比較了運行所需的時間。完成該帖後,我將使用鏈接更新此答案。只是為了讓你知道,我已經將上面的內容與lodash的內容進行了比較,如果瀏覽器不支持Map,它就勝過了lodash!請注意,我沒有使用Array.prototype.indexOfArray.prototype.includes包含exlcudeValues MapObject更快地查詢!(https://jsperf.com/array-without-benchmark-against-lodash


以下是使用JavaScript從數組中刪除項目的幾種方法。

所描述的所有方法都不會改變原始數組 ,而是創建一個新數組

如果您知道項目的索引

假設您有一個數組,並且想要移除位置i中的項目。

一種方法是使用slice()

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const i = 3
const filteredItems = items.slice(0, i-1).concat(items.slice(i, items.length))

console.log(filteredItems)

slice()使用它接收的索引創建一個新數組。 我們只是創建一個新數組,從開始到我們想要刪除的索引,並從我們刪除的數據到數組末尾之後的第一個位置連接另一個數組。

如果你知道價值

在這種情況下,一個不錯的選擇是使用filter() ,它提供了更具說明性的方法:

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valueToRemove = 'c'
const filteredItems = items.filter(item => item !== valueToRemove)

console.log(filteredItems)

這使用ES6箭頭功能。 您可以使用傳統功能來支持舊版瀏覽器:

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valueToRemove = 'c'
const filteredItems = items.filter(function(item) {
  return item !== valueToRemove
})

console.log(filteredItems)

或者您可以使用Babel並將ES6代碼轉發回ES5,使其更易於瀏覽舊瀏覽器,同時在代碼中編寫現代JavaScript。

刪除多個項目

如果不是單個項目,您想要刪除多個項目,該怎麼辦?

讓我們找到最簡單的解決方案。

按索引

您只需創建一個函數並刪除系列中的項目:

const items = ['a', 'b', 'c', 'd', 'e', 'f']

const removeItem = (items, i) =>
  items.slice(0, i-1).concat(items.slice(i, items.length))

let filteredItems = removeItem(items, 3)
filteredItems = removeItem(filteredItems, 5)
//["a", "b", "c", "d"]

console.log(filteredItems)

按價值

您可以在回調函數中搜索包含:

const items = ['a', 'b', 'c', 'd', 'e', 'f']
const valuesToRemove = ['c', 'd']
const filteredItems = items.filter(item => !valuesToRemove.includes(item))
// ["a", "b", "e", "f"]

console.log(filteredItems)

避免改變原始數組

splice() (不要與slice()混淆)改變原始數組,應該避免。

(最初發佈於https://flaviocopes.com/how-to-remove-item-from-array/


如果要刪除已刪除位置的新數組,可以始終刪除特定元素並過濾掉數組。 對於沒有實現過濾方法的瀏覽器,可能需要對數組對象進行擴展,但從長遠來看,它更容易,因為你所做的只是:

var my_array = [1,2,3,4,5,6];
delete my_array[4];
console.log(my_array.filter(function(a){return typeof a !== 'undefined';}));

應該顯示[1, 2, 3, 4, 6]


我是JavaScript的新手,需要這個功能。 我只寫了這個:

function removeFromArray(array, item, index) {
  while((index = array.indexOf(item)) > -1) {
    array.splice(index, 1);
  }
}

然後,當我想使用它時:

//Set-up some dummy data
var dummyObj = {name:"meow"};
var dummyArray = [dummyObj, "item1", "item1", "item2"];

//Remove the dummy data
removeFromArray(dummyArray, dummyObj);
removeFromArray(dummyArray, "item2");

輸出 - 正如所料。 [“item1”,“item1”]

您可能有不同的需求,因此您可以輕鬆修改它以適應它們。 我希望這可以幫助別人。


John Resig 發布了一個很好的實現

// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};

如果您不想擴展全局對象,則可以執行以下操作:

// Array Remove - By John Resig (MIT Licensed)
Array.remove = function(array, from, to) {
    var rest = array.slice((to || from) + 1 || array.length);
    array.length = from < 0 ? array.length + from : from;
    return array.push.apply(array, rest);
};

但我發布這個的主要原因是警告用戶不要使用該頁面評論中建議的替代實現(2007年12月14日):

Array.prototype.remove = function(from, to){
  this.splice(from, (to=[0,from||1,++to-from][arguments.length])<0?this.length+to:to);
  return this.length;
};

它起初似乎運行良好,但是通過一個痛苦的過程我發現它在嘗試刪除數組中倒數第二個元素時失敗了。 例如,如果您有一個10個元素的數組,並嘗試使用以下方法刪除第9個元素:

myArray.remove(8);

最終得到一個8元素陣列。 不知道為什麼,但我確認John的原始實現沒有這個問題。


太老了回复,但可能通過提供謂詞而不是值來幫助某人。

注意:它將更新給定的數組,並返回受影響的行

用法

var removed = helper.removeOne(arr, row => row.id === 5 );

var removed = helper.remove(arr, row => row.name.startsWith('BMW'));

定義

var helper = {

    // Remove and return the first occurrence     

    removeOne: function(array, predicate) {
        for (var i = 0; i < array.length; i++) {
            if (predicate(array[i])) {
                return array.splice(i, 1);
            }
        }
    },

    // Remove and return all occurrences  

    remove: function(array, predicate) {
        var removed = [];

        for (var i = 0; i < array.length;) {

            if (predicate(array[i])) {
                removed.push(array.splice(i, 1));
                continue;
            }

            i++;                
        }

        return removed;
    }
};

Underscore.js可用於解決多個瀏覽器的問題。 它使用內置瀏覽器方法(如果存在)。 如果它們不存在,就像舊的Internet Explorer版本一樣,它使用自己的自定義方法。

從數組中刪除元素的簡單示例(來自網站):

_.without([1, 2, 1, 0, 3, 1, 4], 0, 1); // => [2, 3, 4]

你有1到9個數組,你想刪除5使用下面的代碼。

var numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];

var newNumberArray = numberArray.filter(m => {
  return m !== 5;
});

console.log("new Array, 5 removed", newNumberArray);

如果你想要多個值ex: - 1,7,8

var numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];

var newNumberArray = numberArray.filter(m => {
  return (m !== 1) && (m !== 7) && (m !== 8);
});

console.log("new Array, 5 removed", newNumberArray);

如果要刪除數組ex中的數組值: - [3,4,5]

var numberArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var removebleArray = [3,4,5];

var newNumberArray = numberArray.filter(m => {
    return !removebleArray.includes(m);
});

console.log("new Array, [3,4,5] removed", newNumberArray);

包括支持的瀏覽器是link


看看這段代碼。 它適用於所有主流瀏覽器

remove_item = function (arr, value) {
    var b = '';
    for (b in arr) {
        if (arr[b] === value) {
            arr.splice(b, 1);
            break;
        }
    }
    return arr;
}

調用此功能

remove_item(array,value);

如果元素有多個實例,則可以執行向後循環以確保不會搞砸索引。

var myElement = "chocolate";
var myArray = ['chocolate', 'poptart', 'poptart', 'poptart', 'chocolate', 'poptart', 'poptart', 'chocolate'];

/* Important code */
for (var i = myArray.length - 1; i >= 0; i--) {
    if (myArray[i] == myElement) myArray.splice(i, 1);
}

現場演示


有兩種主要方法:

  1. splice()anArray.splice(index, 1);

  2. 刪除delete anArray[index];

對數組使用delete時要小心。 刪除對象的屬性很好,但對數組不太好。 最好將splice用於數組。

請記住,當您對數組使用delete時, anArray.length可能會得到錯誤的結果。 換句話說, delete將刪除元素但不會更新length屬性的值。

使用刪除後,您還可能會在索引號中出現漏洞,例如,您最終可能會使用刪除之前的索引1,3,4,8,9,11和長度。 在這種情況下,所有索引for循環都會崩潰,因為索引不再是順序的。

如果由於某種原因被迫使用delete ,那麼當需要循環遍歷數組時,應該使用for each循環。 事實上,如果可能的話,總是避免使用索引for循環。 這樣,代碼將更加健壯,並且不易出現索引問題。


取決於你是否想留空。

如果你想要一個空插槽,刪除就可以了:

delete array[ index ];

如果不這樣做,則應使用splice方法:

array.splice( index, 1 );

如果你需要該項的值,你可以只存儲返回的數組的元素:

var value = array.splice( index, 1 )[0];

如果你想以某種順序執行它,你可以使用array.pop()作為最後一個,或者使用array.shift()作為第一個(並且兩者都返回項的值)。

如果您不知道項目的索引,可以使用array.indexOf( item )來獲取它(在if()中獲取一個項目或在while()中獲取所有項目。 array.indexOf( item )返回索引,如果未找到則返回-1。


一位朋友在Internet Explorer 8遇到問題,並向我展示了他的所作所為。 我告訴他這是錯的,他告訴我他在這裡得到了答案。 當前的最佳答案不適用於所有瀏覽器(例如​​Internet Explorer 8),它只會刪除第一次出現的項目。

從數組中刪除所有實例

function remove(arr, item) {
    for (var i = arr.length; i--;) {
        if (arr[i] === item) {
            arr.splice(i, 1);
        }
    }
}

它向後循環遍歷數組(因為索引和長度將隨著項目的移除而改變)並刪除項目(如果已找到)。 它適用於所有瀏覽器。


更現代的ECMAScript 2015 (以前稱為Harmony或ES 6)方法。 鑑於:

const items = [1, 2, 3, 4];
const index = 2;

然後:

items.filter((x, i) => i !== index);

產量:

[1, 2, 4]

您可以使用Babelpolyfill服務來確保跨瀏覽器能夠很好地支持它。


好的,例如你有以下數組:

var num = [1, 2, 3, 4, 5];

我們想刪除4號,你可以簡單地做下面的代碼:

num.splice(num.indexOf(4), 1); //num will be [1, 2, 3, 5];

如果重新使用此函數,則編寫一個可重用的函數,該函數將附加到Native數組函數,如下所示:

Array.prototype.remove = Array.prototype.remove || function(x) {
  const i = this.indexOf(x);
  if(i===-1) return;
  this.splice(i, 1); //num.remove(5) === [1, 2, 3];
}

但是,如果您使用下面的數組而不是數組中的[5] s,那怎麼樣?

var num = [5, 6, 5, 4, 5, 1, 5];

我們需要一個循環來檢查所有這些,但更容易和更有效的方法是使用內置的JavaScript函數,所以我們編寫一個使用過濾器的函數,如下所示:

const _removeValue = (arr, x) => arr.filter(n => n!==x);
//_removeValue([1, 2, 3, 4, 5, 5, 6, 5], 5) //return [1, 2, 3, 4, 6]

還有第三方庫可以幫助你做這些,比如Lodash或Underscore,有關更多信息,請查看lodash _.pull,_.pullAt或_.without。


丹的斷言“刪除”非常緩慢,而他發布的基準則受到懷疑。所以我在Chrome 59中自己進行了測試。看起來'刪除'的速度大約慢了30倍:

var iterationsTotal = 10000000;  // 10 million
var o;
var t1 = Date.now(),t2;
for (let i=0; i<iterationsTotal; i++) {
   o = {a:1,b:2,c:3,d:4,e:5};
   delete o.a; delete o.b; delete o.c; delete o.d; delete o.e;
}
console.log ((t2=Date.now())-t1);  // 6135
for (let i=0; i<iterationsTotal; i++) {
   o = {a:1,b:2,c:3,d:4,e:5};
   o.a = o.b = o.c = o.d = o.e = undefined;
}
console.log (Date.now()-t2);  // 205

請注意,我有意在一個循環週期中執行多個“刪除”操作,以最大限度地減少其他操作所造成的影響。





javascript arrays