Bagaimana saya bisa menghapus item tertentu dari array?

8297

Saya memiliki array angka dan saya menggunakan .push()metode ini untuk menambahkan elemen ke dalamnya.

Apakah ada cara sederhana untuk menghapus elemen tertentu dari array?

Saya mencari yang setara dengan sesuatu seperti:

array.remove(number);

Saya harus menggunakan JavaScript inti . Kerangka kerja tidak diizinkan.

Pejalan
sumber

Jawaban:

11894

Temukan indexelemen array yang ingin Anda hapus menggunakan indexOf, dan kemudian hapus indeks itu dengan splice.

Metode splice () mengubah konten array dengan menghapus elemen yang ada dan / atau menambahkan elemen baru.

const array = [2, 5, 9];

console.log(array);

const index = array.indexOf(5);
if (index > -1) {
  array.splice(index, 1);
}

// array = [2, 9]
console.log(array); 

Parameter kedua spliceadalah jumlah elemen yang akan dihapus. Catatan yang splicemengubah array di tempat dan mengembalikan array baru yang mengandung elemen yang telah dihapus.


Untuk alasan kelengkapan, berikut adalah fungsinya. Fungsi pertama menghapus hanya kejadian tunggal (yaitu menghapus pertandingan pertama 5dari [2,5,9,1,5,8,5]), sedangkan fungsi kedua menghapus semua kejadian:

function removeItemOnce(arr, value) { 
    var index = arr.indexOf(value);
    if (index > -1) {
        arr.splice(index, 1);
    }
    return arr;
}

function removeItemAll(arr, value) {
    var i = 0;
    while (i < arr.length) {
        if(arr[i] === value) {
            arr.splice(i, 1);
        } else {
            ++i;
        }
    }
    return arr;
}
Tom Wadley
sumber
15
@ Peter, ya Anda mungkin benar. Artikel ini menjelaskan lebih banyak dan mempunyai solusi untuk peramban yang tidak kompatibel: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…
Tom Wadley
33
@AlexandreWiechersVaz Tentu saja itu menjaga ketertiban, jika tidak maka itu akan benar-benar tidak berharga
TheZ
15
Anda dapat mengatasi masalah dukungan browser IE dengan memasukkan kode yang diberikan di sini
15
@AdrianP. array.indexOf(testValue)pada array kosong akan menjadi -1, dan jika Anda menguji untuk itu maka tidak ada sambungan. Mungkin jawabannya sudah berubah sejak itu.
UpTheCreek
13
IE 7, IE8, IE9, IE10 tidak didukung oleh Microsoft sendiri, mengapa pengembang web harus mendukung browser lama itu? Cukup tampilkan pemberitahuan tentang meningkatkan peramban! support.microsoft.com/en-us/lifecycle/…
Lukas Liesis
1268

Saya tidak tahu bagaimana Anda mengharapkan array.remove(int)untuk berperilaku. Ada tiga kemungkinan yang dapat saya pikirkan yang mungkin Anda inginkan.

Untuk menghapus elemen array pada indeks i:

array.splice(i, 1);

Jika Anda ingin menghapus setiap elemen dengan nilai numberdari array:

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

Jika Anda hanya ingin membuat elemen di indeks itidak ada lagi, tetapi Anda tidak ingin indeks elemen lain berubah:

delete array[i];
Peter Olson
sumber
335
deletebukan cara yang tepat untuk menghapus elemen dari array!
Felix Kling
71
@ Feliksling Tergantung, itu berfungsi jika Anda ingin membuatnya sehingga array.hasOwnProperty(i)kembali falsedan memiliki elemen di posisi itu kembali undefined. Tapi saya akui itu bukan hal yang sangat umum untuk dilakukan.
Peter Olson
88
deletetidak akan memperbarui panjang array tidak benar-benar menghapus elemen, hanya menggantinya dengan nilai spesial undefined.
diosney
34
@diosney Saya tidak tahu apa yang Anda maksud ketika Anda mengatakan itu tidak benar-benar menghapus elemen. Lebih jauh, ia melakukan lebih dari sekadar mengganti nilai pada indeks itu dengan undefined: ia menghilangkan indeks dan nilai dari array, yaitu setelah delete array[0], "0" in arrayakan mengembalikan false.
Peter Olson
17
@GrantGryczan Maaf, saya tidak setuju. Saya tidak melihat perlunya dihapus. Teks di atas dengan jelas menjelaskan apa yang dilakukannya, dan membantu orang-orang yang tidak tahu apa yang deleteharus dipahami mengapa tidak berfungsi seperti yang mereka harapkan.
Peter Olson
1207

Diedit pada 2016 Oktober

  • Lakukan dengan sederhana, intuitif, dan eksplisit ( pisau cukur Occam )
  • Lakukan itu tidak berubah (array asli tetap tidak berubah)
  • Lakukan dengan fungsi JavaScript standar, jika browser Anda tidak mendukungnya - gunakan polyfill

Dalam contoh kode ini saya menggunakan fungsi "array.filter (...)" untuk menghapus item yang tidak diinginkan dari array. Fungsi ini tidak mengubah array asli dan membuat yang baru. Jika browser Anda tidak mendukung fungsi ini (mis. Internet Explorer sebelum versi 9, atau Firefox sebelum versi 1.5), pertimbangkan untuk menggunakan filter polyfill dari Mozilla .

Menghapus item (ECMA-262 Edition 5 kode alias JavaScript gaya lama)

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 ]

Menghapus item (kode ECMAScript 6)

let value = 3

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

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

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

PENTINGECMAScript 6 "() => {}" sintaks fungsi panah sama sekali tidak didukung di Internet Explorer, Chrome sebelum versi 45, Firefox sebelum versi 22, dan Safari sebelum versi 10. Untuk menggunakan sintaks ECMAScript 6 di browser lama, Anda dapat menggunakan BabelJS .


Menghapus banyak item (kode ECMAScript 7)

Keuntungan tambahan dari metode ini adalah Anda dapat menghapus banyak item

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 ]

PENTING "array.includes (...)" fungsi sama sekali tidak didukung di Internet Explorer, Chrome sebelum versi 47, Firefox sebelum versi 43, Safari versi sebelum 9, dan versi Edge sebelum 14 jadi di sini adalah polyfill dari Mozilla .

Menghapus banyak item (di masa depan, mungkin)

Jika proposal "This-Binding Syntax" pernah diterima, Anda akan dapat melakukan ini:

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

Coba sendiri di BabelJS :)

Referensi

ujeenator
sumber
6
tetapi, kadang-kadang kita ingin menghapus elemen dari array asli (tidak dapat diubah), misalnya array yang digunakan dalam Angular 2 * ngFor directive
Ravinder Payal
43
Lebih baik daripada solusi yang diterima karena tidak mengasumsikan hanya satu pertandingan yang cocok dan kekekalan lebih disukai
Greg
13
filterharus jauh lebih lambat untuk array besar?
Nathan
3
Apa maksud dari ketidakberdayaan yang disebutkan jika Anda menggunakan penugasan variabel yang sama dalam contoh Anda? :)
mench
12
Ini jawaban yang bagus. Splice adalah fungsi khusus untuk bermutasi tidak menyaring. filtermungkin memiliki kinerja lebih lambat tetapi kode lebih aman dan lebih baik. Selain itu, Anda dapat memfilter menurut indeks dengan menentukan argumen kedua dalam lambda:arr.filter((x,i)=>i!==2)
Matius
449

Itu tergantung pada apakah Anda ingin menyimpan tempat kosong atau tidak.

Jika Anda ingin slot kosong, hapus tidak apa-apa:

delete array[index];

Jika tidak, Anda harus menggunakan metode sambatan :

array.splice(index, 1);

Dan jika Anda membutuhkan nilai item itu, Anda bisa menyimpan elemen array yang dikembalikan:

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

Jika Anda ingin melakukannya dalam urutan tertentu, Anda dapat menggunakan array.pop()yang terakhir atauarray.shift() yang pertama (dan keduanya mengembalikan nilai item juga).

Dan jika Anda tidak tahu indeks item tersebut, Anda dapat menggunakannya array.indexOf(item)untuk mendapatkannya (dalam if()untuk mendapatkan satu item atau dalam while()untuk mendapatkan semuanya). array.indexOf(item)mengembalikan indeks atau -1 jika tidak ditemukan. 

xavierm02
sumber
25
deletebukan cara yang tepat untuk menghapus elemen dari array !!
Progo
16
Jika Anda ingin "mengosongkan slot", gunakan array[index] = undefined;. Menggunakan deleteakan menghancurkan optimasi.
Bergi
4
@ Yakub komentar yang sangat baik karena untuk memahami bahwa saya kehilangan banyak waktu dan berpikir kode aplikasi saya entah bagaimana rusak ...
Pascal
Paragraf terakhir dengan penjelasan tentang apa yang Anda dapatkan dari indexOf benar-benar membantu
A. D'Alfonso
277

Seorang teman mengalami masalah di Internet Explorer 8 dan menunjukkan kepada saya apa yang dia lakukan. Saya mengatakan kepadanya bahwa itu salah, dan dia memberi tahu saya bahwa dia mendapatkan jawabannya di sini. Jawaban teratas saat ini tidak akan berfungsi di semua browser (misalnya Internet Explorer 8), dan itu hanya akan menghilangkan kemunculan item pertama.

Hapus SEMUA instance dari array

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

Itu loop melalui array mundur (karena indeks dan panjang akan berubah ketika item dihapus) dan menghapus item jika ditemukan. Ini bekerja di semua browser.

Ben Lesh
sumber
11
@sroes itu tidak boleh karena loop dimulai i = arr.length -1atau i--membuatnya sama dengan indeks max. arr.lengthhanyalah nilai awal untuk i. i--akan selalu truthy (dan mengurangi oleh 1 di setiap loop op) sampai sama 0(nilai falsy) dan loop kemudian akan berhenti.
gmajivu
1
Fungsi kedua agak tidak efisien. Pada setiap iterasi "indexOf" akan memulai pencarian dari awal array.
ujeenator
3
@AmberdeBlack, pada koleksi dengan lebih dari 1 kemunculan item , jauh lebih baik untuk memanggil metode filter sebagai gantinya arr.filter(function (el) { return el !== item }), menghindari keharusan untuk memutasikan array beberapa kali. Ini menghabiskan sedikit lebih banyak memori, tetapi beroperasi jauh lebih efisien, karena ada sedikit pekerjaan yang perlu dilakukan.
Eugene Kuzmenko
1
@Aley, ini hanya tersedia dari IE9 +. Masih ada kemungkinan itu tidak akan berhasil.
ujeenator
1
Jawaban ini berhasil bagi saya karena saya perlu beberapa item dihapus tetapi tidak dalam urutan tertentu. Kemajuan mundur untuk loop di sini menangani menghapus item dari array dengan sempurna.
mintedsky
172

Ada dua pendekatan utama:

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

  2. hapus :delete anArray[index];

Hati-hati saat Anda menggunakan delete untuk sebuah array. Ini bagus untuk menghapus atribut objek, tetapi tidak begitu bagus untuk array. Lebih baik digunakansplice untuk array.

Ingatlah bahwa ketika Anda menggunakan deletearray, Anda bisa mendapatkan hasil yang salahanArray.length . Dengan kata lain,delete akan menghapus elemen, tetapi itu tidak akan memperbarui nilai properti panjang.

Anda juga bisa berharap memiliki lubang dalam angka indeks setelah menggunakan delete, mis. Anda bisa berakhir dengan memiliki indeks 1, 3, 4, 8, 9, dan 11 dan panjang seperti sebelumnya sebelum menggunakan delete. Dalam hal itu, semua diindeksfor loop yang akan macet, karena indeks tidak lagi berurutan.

Jika Anda terpaksa menggunakan deleteuntuk beberapa alasan, maka Anda harus menggunakan for eachloop ketika Anda perlu untuk loop melalui array. Faktanya, selalu hindari menggunakan forloop yang diindeks , jika memungkinkan. Dengan begitu kode akan lebih kuat dan kurang rentan terhadap masalah dengan indeks.

Sasa
sumber
144
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)

Zirak
sumber
14
Saya bukan penggemar pendekatan ini. Jika Anda akhirnya menggunakan pustaka atau kerangka kerja yang berbeda, mereka dapat berakhir saling bertentangan.
Charlie Kilian
10
Gagasan buruk, lihat posting ini: stackoverflow.com/questions/948358/array-prototype-problem
MMeah
10
Jika Anda melakukan for inpada array, Anda sudah memiliki masalah.
Zirak
2
jika Anda melakukannya for inpada array, Anda sudah memiliki masalah yang lebih besar.
Rainb
gunakan Object.defineProperty stackoverflow.com/a/35518127/3779853 dan Anda siap melakukannya.
phil294
105

Tidak perlu menggunakan indexOfatau splice. Namun, berkinerja lebih baik jika Anda hanya ingin menghapus satu kemunculan elemen.

Temukan dan pindahkan (pindah):

function move(arr, val) {
  var j = 0;
  for (var i = 0, l = arr.length; i < l; i++) {
    if (arr[i] !== val) {
      arr[j++] = arr[i];
    }
  }
  arr.length = j;
}

Gunakan indexOfdan splice(indeks):

function indexof(arr, val) {
  var i;
  while ((i = arr.indexOf(val)) != -1) {
    arr.splice(i, 1);
  }
}

Gunakan hanya splice(sambungan):

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

Run-times pada nodejs untuk array dengan 1000 elemen (rata-rata lebih dari 10000 run):

indexof sekitar 10x lebih lambat daripada bergerak . Bahkan jika ditingkatkan dengan menghapus panggilan ke indexOfdalam sambungan itu melakukan jauh lebih buruk daripada bergerak .

Remove all occurrences:
    move 0.0048 ms
    indexof 0.0463 ms
    splice 0.0359 ms

Remove first occurrence:
    move_one 0.0041 ms
    indexof_one 0.0021 ms
slosd
sumber
5
Sepertinya metode 'pindah' ​​yang disajikan di sini harus berfungsi di semua browser, dan juga menghindari membuat array ekstra; kebanyakan solusi lain di sini memiliki satu atau kedua masalah ini. Saya pikir ini pantas mendapatkan lebih banyak suara, bahkan jika itu tidak terlihat "cantik".
sockmonk
73

Ini memberikan predikat alih-alih nilai.

CATATAN: itu akan memperbarui array yang diberikan, dan mengembalikan baris yang terpengaruh.

Pemakaian

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

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

Definisi

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;
    }
};
amd
sumber
Saya tidak tahu bahwa Anda memerlukan cek -1 (i> -1). Juga, saya pikir fungsi-fungsi ini lebih berfungsi seperti filter daripada menghapus. Jika Anda melewatkan row.id === 5, itu akan menghasilkan array dengan hanya id 5, sehingga ia melakukan kebalikan dari menghapus. Itu akan terlihat bagus di ES2015: var result = ArrayHelper.remove (myArray, row => row.id === 5);
What Would Be Cool
@WhatWouldBeCool fungsi ini memodifikasi array asli, dan mengembalikan item yang dihapus alih-alih menyalin hasilnya ke array baru
amd
68

Anda dapat melakukannya dengan mudah dengan metode filter :

function remove(arrOriginal, elementToRemove){
    return arrOriginal.filter(function(el){return el !== elementToRemove});
}
console.log(remove([1, 2, 1, 0, 3, 1, 4], 1));

Ini menghapus semua elemen dari array dan juga bekerja lebih cepat dari kombinasi slicedan indexOf.

Salvador Dali
sumber
3
Apakah Anda memiliki sumber tentang ini lebih cepat?
user3711421
2
Solusi yang bagus. Tapi seperti yang Anda menunjukkan, tetapi penting untuk membuat botak, tidak menghasilkan hasil yang sama seperti slice dan indexOf karena akan menghapus semua kejadian dari 1
user3711421
1
@ user3711421 ini karena hanya mengiris dan indexOf tidak melakukan apa yang dia inginkan "untuk menghapus elemen tertentu". Ini menghapus elemen hanya sekali, ini menghapus elemen tertentu tidak peduli berapa banyak dari mereka yang Anda miliki
Salvador Dali
66

John Resig memposting implementasi yang baik :

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

Jika Anda tidak ingin memperluas objek global, Anda dapat melakukan sesuatu seperti berikut ini, sebagai gantinya:

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

Tetapi alasan utama saya memposting ini adalah untuk memperingatkan pengguna terhadap implementasi alternatif yang disarankan dalam komentar di halaman itu (14 Des 2007):

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

Tampaknya bekerja dengan baik pada awalnya, tetapi melalui proses yang menyakitkan saya menemukan itu gagal ketika mencoba untuk menghapus elemen kedua hingga terakhir dalam sebuah array. Misalnya, jika Anda memiliki array 10-elemen dan Anda mencoba menghapus elemen ke-9 dengan ini:

myArray.remove(8);

Anda berakhir dengan array 8-elemen. Tidak tahu mengapa, tetapi saya mengkonfirmasi implementasi asli John tidak memiliki masalah ini.

Roger
sumber
Baru belajar dengan cara yang sulit mengapa itu adalah ide yang baik untuk menggunakan Object.prototype.hasOwnPropertyselalu ¬¬
Davi Fiamenghi
64

Underscore.js dapat digunakan untuk menyelesaikan masalah dengan banyak browser. Ini menggunakan metode browser built-in jika ada. Jika mereka tidak ada seperti dalam kasus versi Internet Explorer yang lebih lama itu menggunakan metode kustom sendiri.

Contoh sederhana untuk menghapus elemen dari array (dari situs web):

_.without([1, 2, 1, 0, 3, 1, 4], 0, 1); // => [2, 3, 4]
Vatsal
sumber
Meskipun elegan dan ringkas, OP hanya menyebutkan inti JS
EigenFool
64

Anda dapat menggunakan ES6. Misalnya untuk menghapus nilai '3' dalam kasus ini:

var array=['1','2','3','4','5','6']
var newArray = array.filter((value)=>value!='3');
console.log(newArray);

Keluaran:

["1", "2", "4", "5", "6"]
rajat44
sumber
4
Jawaban ini bagus karena ia membuat salinan array asli, alih-alih memodifikasi yang asli secara langsung.
Claudio Holanda
Catatan: Array.prototype.filter adalah ECMAScript 5.1 (Tidak ada IE8). untuk solusi yang lebih spesifik: stackoverflow.com/a/54390552/8958729
Chang
54

Jika Anda ingin array baru dengan posisi yang dihapus dihapus, Anda selalu dapat menghapus elemen tertentu dan menyaring array. Mungkin perlu ekstensi objek array untuk browser yang tidak menerapkan metode filter, tetapi dalam jangka panjang lebih mudah karena semua yang Anda lakukan adalah ini:

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

Itu harus ditampilkan [1, 2, 3, 4, 6].

Loupax
sumber
45

Lihatlah kode ini. Ini bekerja di setiap browser utama .

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

Panggil fungsi ini

remove_item(array,value);
Ekramul Hoque
sumber
4
@RolandIllig Kecuali penggunaan for in-loop dan fakta bahwa skrip bisa berhenti lebih awal, dengan mengembalikan hasil dari loop secara langsung. Hasil positifnya masuk akal;)
yckart
1
Ini adalah pendekatan yang sangat baik untuk array kecil. Ini bekerja di setiap browser, menggunakan kode minimal dan intuitif, dan tanpa kerangka kerja yang rumit, shims, atau polyfill.
Beejor
Saya juga harus mengulangi komentar yckart yang for( i = 0; i < arr.length; i++ )akan menjadi pendekatan yang lebih baik karena mempertahankan indeks yang tepat versus pesanan apa pun yang browser memutuskan untuk menyimpan item (dengan for in). Melakukannya juga memungkinkan Anda mendapatkan indeks array dari suatu nilai jika Anda membutuhkannya.
Beejor
41

Anda dapat menggunakan lodash _.pull (mutate array), _.pullAt (mutate array) atau _.without (tidak bermutasi array),

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']
Chun Yang
sumber
2
Itu bukan inti JS seperti yang diminta OP, bukan?
some-non-descript-user
12
@ some-non-descript-user Anda benar. Tetapi banyak pengguna seperti saya datang ke sini mencari jawaban umum bukan hanya untuk OP saja.
Chun Yang
@ ChunYang Anda benar sekali. Saya sudah menggunakan lodash, mengapa tidak hanya menggunakannya jika menghemat waktu.
int-i
38

ES6 & tanpa mutasi: (Oktober 2016)

const removeByIndex = (list, index) =>
      [
        ...list.slice(0, index),
        ...list.slice(index + 1)
      ];
         
output = removeByIndex([33,22,11,44],1) //=> [33,11,44]
      
console.log(output)

Abdennour TOUMI
sumber
Mengapa tidak menggunakannya saja filter? array.filter((_, index) => index !== removedIndex);.
user4642212
@ user4642212 Anda benar! juga, saya menyukai garis bawah gaya Golang
Abdennour TOUMI
36

Menghapus elemen / string tertentu dari array dapat dilakukan dalam satu-liner:

theArray.splice(theArray.indexOf("stringToRemoveFromArray"), 1);

dimana:

Array : array yang ingin Anda hapus dari sesuatu

stringToRemoveFromArray : string yang ingin Anda hapus dan 1 adalah jumlah elemen yang ingin Anda hapus.

CATATAN : Jika "stringToRemoveFromArray" tidak ditemukan dalam array Anda, ini akan menghapus elemen terakhir array.

Itu selalu praktik yang baik untuk memeriksa apakah elemen ada di array Anda terlebih dahulu, sebelum menghapusnya.

if (theArray.indexOf("stringToRemoveFromArray") >= 0){
   theArray.splice(theArray.indexOf("stringToRemoveFromArray"), 1);
}

Jika Anda memiliki akses ke versi Ecmascript yang lebih baru di komputer klien Anda (PERINGATAN, mungkin tidak berfungsi di stasiun yang lebih lama):

var array=['1','2','3','4','5','6']
var newArray = array.filter((value)=>value!='3');

Di mana '3' adalah nilai yang ingin Anda hapus dari array. Array kemudian menjadi:['1','2','4','5','6']

Max Alexander Hanna
sumber
Ini adalah jawaban yang berfungsi untuk saya ketika mencoba memperbarui array berdasarkan toggling tombol radio.
jdavid05
4
Hati-hati, jika "stringToRemoveFromArray"tidak ditemukan array Anda, ini akan menghapus elemen terakhir array.
Fusion
35

Berikut adalah beberapa cara untuk menghapus item dari array menggunakan JavaScript .

Semua metode yang dijelaskan tidak bermutasi array asli , dan bukannya membuat yang baru.

Jika Anda tahu indeks suatu barang

Misalkan Anda memiliki array, dan Anda ingin menghapus item di posisinya i.

Salah satu metode adalah menggunakan slice():

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

console.log(filteredItems)

slice()membuat array baru dengan indeks yang diterimanya. Kami cukup membuat array baru, dari awal hingga indeks yang ingin kami hapus, dan menggabungkan array lain dari posisi pertama mengikuti yang kami hapus ke akhir array.

Jika Anda tahu nilainya

Dalam hal ini, satu opsi yang baik adalah menggunakan filter(), yang menawarkan pendekatan yang lebih deklaratif :

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

console.log(filteredItems)

Ini menggunakan fungsi panah ES6. Anda dapat menggunakan fungsi tradisional untuk mendukung browser lama:

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

console.log(filteredItems)

atau Anda dapat menggunakan Babel dan mengubah kode ES6 kembali ke ES5 untuk membuatnya lebih mudah dicerna oleh browser lama, namun menulis JavaScript modern dalam kode Anda.

Menghapus banyak item

Bagaimana jika alih-alih satu item, Anda ingin menghapus banyak item?

Mari temukan solusi paling sederhana.

Menurut indeks

Anda bisa membuat fungsi dan menghapus item secara seri:

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)

Berdasarkan nilai

Anda dapat mencari penyertaan di dalam fungsi panggilan balik:

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)

Hindari mutasi array asli

splice()(jangan dikacaukan dengan slice()) bermutasi array asli, dan harus dihindari.

(awalnya diposting di https://flaviocopes.com/how-to-remove-item-from-array/ )

Flavio Copes
sumber
34

OK, misalnya Anda memiliki array di bawah ini:

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

Dan kami ingin menghapus nomor 4. Anda cukup menggunakan kode di bawah ini:

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

Jika Anda menggunakan kembali fungsi ini, Anda menulis fungsi yang dapat digunakan kembali yang akan dilampirkan ke fungsi array asli seperti di bawah ini:

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

Tetapi bagaimana jika Anda memiliki array di bawah ini dengan beberapa [5] dalam array?

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

Kami membutuhkan loop untuk memeriksa semuanya, tetapi cara yang lebih mudah dan lebih efisien adalah menggunakan fungsi JavaScript bawaan, jadi kami menulis fungsi yang menggunakan filter seperti di bawah ini sebagai gantinya:

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]

Juga ada perpustakaan pihak ketiga yang membantu Anda melakukan ini, seperti Lodash atau Underscore. Untuk informasi lebih lanjut, lihat lodash _.pull, _.pullAt atau _.without.

Alireza
sumber
Ada kesalahan ketik kecil. Mohon perbaiki. this.splice(num.indexOf(x), 1);=>this.splice(this.indexOf(x), 1);
TheGwa
Tolong jangan menambah bawaan (melampirkan fungsi ke Array.prototype) dalam JavaScript. Ini secara luas dianggap sebagai praktik buruk.
aikeru
Saya setuju itu bukan hal terbaik untuk dilakukan di dunia, tetapi dalam hal ini bagaimana Anda bisa meneruskannya ke fungsi?
Alireza
Anda harus memeriksa indeks. Jika indeks = -1, sambatan (-1,1) akan menghapus elemen terakhir
Richard Chan
29

Saya cukup baru dalam JavaScript dan membutuhkan fungsi ini. Saya hanya menulis ini:

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

Lalu ketika saya ingin menggunakannya:

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

Output - Seperti yang diharapkan. ["item1", "item1"]

Anda mungkin memiliki kebutuhan yang berbeda dari saya, sehingga Anda dapat dengan mudah memodifikasinya agar sesuai dengan mereka. Saya harap ini membantu seseorang.

sofiax
sumber
1
Ini akan memiliki perilaku yang buruk jika array Anda sangat panjang dan ada beberapa contoh elemen di dalamnya. Metode indexOf dari array akan dimulai di awal setiap waktu, sehingga biaya Anda akan menjadi O (n ^ 2).
Zag
@Zag: Memiliki nama: Algoritma Shlemiel the Painter
Peter Mortensen
27

Jika Anda memiliki objek kompleks dalam array, Anda dapat menggunakan filter? Dalam situasi di mana $ .inArray atau array.splice tidak mudah digunakan. Terutama jika objek mungkin dangkal dalam array.

Misalnya jika Anda memiliki objek dengan bidang Id dan Anda ingin objek dihapus dari array:

this.array = this.array.filter(function(element, i) {
    return element.id !== idToRemove;
});
tebal
sumber
Ini adalah bagaimana saya suka melakukannya. Menggunakan fungsi panah, ini bisa menjadi satu garis. Saya ingin tahu tentang kinerja. Juga tidak ada artinya jika ini menggantikan array. Kode apa pun dengan referensi ke array lama tidak akan melihat perubahan.
joeytwiddle
27

Saya ingin menjawab berdasarkan ECMAScript 6 . Asumsikan, Anda memiliki array seperti di bawah ini:

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

Jika Anda ingin menghapus pada indeks khusus seperti 2, tulis kode di bawah ini:

arr.splice(2, 1); //=> arr became [1,2,4]

Tetapi jika Anda ingin menghapus item khusus suka 3dan Anda tidak tahu indeksnya, lakukan seperti di bawah ini:

arr = arr.filter(e => e !== 3); //=> arr became [1,2,4]

Petunjuk : silakan gunakan fungsi panah untuk memfilter panggilan balik kecuali Anda akan mendapatkan array kosong.

Amerika
sumber
25

Pembaruan: Metode ini disarankan hanya jika Anda tidak dapat menggunakan ECMAScript 2015 (sebelumnya dikenal sebagai ES6). Jika Anda dapat menggunakannya, jawaban lain di sini menyediakan implementasi yang lebih rapi.


Inti ini di sini akan menyelesaikan masalah Anda, dan juga menghapus semua kemunculan argumen, bukan hanya 1 (atau nilai yang ditentukan).

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

Pemakaian:

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]
zykadelic
sumber
25

Performa

Hari ini (2019-12-09) Saya melakukan tes kinerja pada macOS v10.13.6 (High Sierra) untuk solusi yang dipilih. Saya menunjukkandelete (A), tapi saya tidak menggunakannya dibandingkan dengan metode lain, karena ia meninggalkan ruang kosong dalam array.

Kesimpulannya

  • solusi tercepat adalah array.splice(C) (kecuali Safari untuk array kecil di mana ia memiliki kedua kalinya)
  • untuk array besar, array.slice+splice(H) adalah solusi tetap tercepat untuk Firefox dan Safari; Array.from(B) tercepat di Chrome
  • solusi yang bisa berubah-ubah biasanya 1,5x-6x lebih cepat dari yang tidak berubah
  • untuk tabel kecil di Safari, secara mengejutkan solusi yang dapat berubah (C) lebih lambat daripada solusi yang tidak dapat diubah (G)

Detail

Dalam tes saya menghapus elemen tengah dari array dengan berbagai cara. Solusi A, C sudah tersedia. Solusi B, D, E, F, G, H tidak dapat diubah.

Hasil untuk array dengan 10 elemen

Masukkan deskripsi gambar di sini

Di Chrome, array.splice(C) adalah solusi tercepat di tempat. The array.filter(D) adalah solusi berubah tercepat. Paling lambat adalah array.slice(F). Anda dapat melakukan tes pada mesin Anda di sini .

Hasil untuk array dengan 1.000.000 elemen

Masukkan deskripsi gambar di sini

Di Chrome, array.splice(C) adalah solusi tercepat di tempat ( delete(C) mirip dengan cepat - tetapi ia meninggalkan slot kosong di array (sehingga tidak melakukan 'penghapusan penuh')). The array.slice-splice(H) adalah solusi berubah tercepat. Paling lambat adalah array.filter(D dan E). Anda dapat melakukan tes pada mesin Anda di sini .

Perbandingan untuk browser: Chrome v78.0.0, Safari v13.0.4, dan Firefox v71.0.0

Masukkan deskripsi gambar di sini

Kamil Kiełczewski
sumber
24

Anda seharusnya tidak pernah mengubah array Anda. Karena ini bertentangan dengan pola pemrograman fungsional. Anda dapat membuat array baru tanpa merujuk array yang ingin Anda ubah data menggunakan metode ECMAScript 6 filter;

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

Misalkan Anda ingin menghapus 5dari array, Anda bisa melakukannya seperti ini:

myArray = myArray.filter(value => value !== 5);

Ini akan memberi Anda array baru tanpa nilai yang ingin Anda hapus. Jadi hasilnya adalah:

 [1, 2, 3, 4, 6]; // 5 has been removed from this array

Untuk pemahaman lebih lanjut, Anda dapat membaca dokumentasi MDN di Array.filter .

Adeel Imran
sumber
21

Yang lebih modern, ECMAScript 2015 (sebelumnya dikenal sebagai Harmony atau ES 6) pendekatan. Diberikan:

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

Kemudian:

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

Menghasilkan:

[1, 2, 4]

Anda dapat menggunakan Babel dan layanan polyfill untuk memastikan ini didukung dengan baik di seluruh browser.

bjfletcher
sumber
4
Perhatikan bahwa .filtermengembalikan array baru, yang tidak persis sama dengan menghapus elemen dari array yang sama. Manfaat dari pendekatan ini adalah Anda dapat menggabungkan metode array secara bersamaan. mis:[1,2,3].filter(n => n%2).map(n => n*n) === [ 1, 9 ]
CodeOcelot
Hebat, jika saya memiliki elemen 600k dalam array dan ingin menghapus 50k pertama, dapatkah Anda membayangkan kelambatan itu? Ini bukan solusi, ada kebutuhan untuk fungsi yang hanya menghapus elemen dan tidak mengembalikan apa pun.
dev1223
@Seraph Untuk itu, Anda mungkin ingin menggunakan spliceatau slice.
bjfletcher
@ bjfletcher Thats bahkan lebih baik, dalam proses penghapusan, hanya mengalokasikan 50K elemen dan membuangnya di suatu tempat. (dengan mengiris elemen 550K, tetapi tanpa membuangnya dari jendela).
dev1223
Saya lebih suka jawaban bjfletcher, yang bisa sesingkat items= items.filter(x=>x!=3). Selain itu, OP tidak menyatakan persyaratan untuk kumpulan data besar.
runningun
21

Anda memiliki 1 hingga 9 dalam array, dan Anda ingin menghapus 5. Gunakan kode di bawah ini:

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


Jika Anda ingin beberapa nilai. Contoh: - 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, 1,7 and 8 removed", newNumberArray);


Jika Anda ingin menghapus nilai array dalam array. Contoh: [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);

Termasuk tautan yang didukung browser .

Thilina Sampath
sumber
19

Saya tahu sudah ada banyak jawaban, tetapi banyak dari mereka tampaknya terlalu memperumit masalah. Berikut ini adalah cara sederhana, rekursif untuk menghapus semua instance kunci - panggilan sendiri hingga indeks tidak ditemukan. Ya, itu hanya bekerja di browser denganindexOf , tetapi sederhana dan dapat dengan mudah diisi.

Fungsi yang berdiri sendiri

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

    if(index === -1) return;

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

Metode prototipe

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

    if(index === -1) return;

    this.splice(index, 1);
    this.removeAll(key);
}
wharding28
sumber
Sekadar catatan, 1 peringatan dengan metode ini adalah potensi stack overflows. Kecuali jika Anda bekerja dengan array besar, Anda seharusnya tidak memiliki masalah.
wharding28
Tapi mengapa harus kembali di tengah? Ini adalah pernyataan yang efektif.
Peter Mortensen
18

Anda dapat melakukan loop mundur untuk memastikan tidak mengacaukan indeks, jika ada beberapa contoh elemen.

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

Demo Langsung

Jeff Noel
sumber