Bir diziden belirli bir öğeyi nasıl kaldırabilirim?


8291

Ben bir sayı dizisi var ve ben .push()ona öğe eklemek için yöntem kullanıyorum .

Bir diziden belirli bir öğeyi kaldırmanın basit bir yolu var mı?

Gibi bir şey eşdeğer arıyorum:

array.remove(number);

Temel JavaScript kullanmak zorundayım . Çerçevelere izin verilmez.

Yanıtlar:


11887

indexKullanarak kaldırmak istediğiniz dizi öğesini bulun indexOfve ardından bu dizini ile kaldırın splice.

Splice () yöntemi, var olan öğeleri kaldırarak ve / veya yeni öğeler ekleyerek bir dizinin içeriğini değiştirir.

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

İkinci parametresi splicekaldırılacak öğe sayısıdır. spliceDiziyi yerinde değiştirdiğini ve kaldırılan öğeleri içeren yeni bir dizi döndürdüğünü unutmayın .


Bütünlük nedeniyle, fonksiyonlar burada. İlk işlev (yani, ilk maçı çıkarılması sadece tek bir oluşumunu ortadan kaldırır 5gelen [2,5,9,1,5,8,5]ikinci işlev tüm oluşumları yok ederken,):

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

15
@Peter, evet haklı olabilirsin. Bu makalede daha fazla açıklanmakta ve uyumsuz tarayıcılar için bir geçici çözümü bulunmaktadır: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…
Tom Wadley

33
@AlexandreWiechersVaz Tabii ki düzeni korur, eğer olmasaydı kesinlikle değersiz olurdu
TheZ


15
@AdrianP. array.indexOf(testValue)boş dizide -1 olacak ve eğer bunun için test ediyorsanız o zaman hiçbir ek. Belki de cevap o zamandan beri değişti.
UpTheCreek

13
IE 7, IE8, IE9, IE10 ar Microsoft tarafından desteklenmiyor, neden web geliştiricileri bu eski tarayıcıları desteklemeli? Tarayıcıyı yükseltme hakkında bildirim göstermeniz yeterli! support.microsoft.com/tr-tr/lifecycle/…
Lukas Liesis

1265

Nasıl beklediğini bilmiyorum array.remove(int) davranmayı . İstediğinizi düşünebileceğim üç olasılık var.

Dizindeki bir dizinin bir öğesini kaldırmak için i:

array.splice(i, 1);

Değer içeren her öğeyi numberdiziden kaldırmak istiyorsanız :

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

Yalnızca dizindeki öğeyi iartık oluşturmak istemiyorsanız, ancak diğer öğelerin dizinlerinin değişmesini istemiyorsanız:

delete array[i];

334
deletediziden bir öğeyi kaldırmanın doğru yolu değildir!
Felix Kling

71
@FelixKling Bağlıdır, array.hasOwnProperty(i)döndürmek falseve o konumdaki öğenin geri dönmesini sağlamak için çalışır undefined. Ama itiraf edeceğim, bunu yapmak çok yaygın bir şey değil.
Peter Olson

88
deletedizinin uzunluğunu güncellemez, öğeyi gerçekten silmez, yalnızca özel değerle değiştirir undefined.
diosney

34
@diosney Elemanı gerçekten silmediğini söylediğinde ne demek istediğini bilmiyorum. Bundan başka, daha basitçe o dizinde değerini değiştirerek daha yapar undefined: o dizini ve diziden değer hem kaldırır, yani sonra delete array[0], "0" in arraysahte dönecektir.
Peter Olson

17
@ GrantGryczan Üzgünüm, katılmıyorum. Bunun kaldırılması gereğini görmüyorum. Yukarıdaki metin ne yaptığını açık bir şekilde açıklıyor ve neyi bilmediğini insanların deleteneden bekledikleri gibi çalışmadığını anlamalarına yardımcı oluyor .
Peter Olson

1204

2016 Ekim tarihinde düzenlendi

  • Basit, sezgisel ve açık yapın ( Occam'ın ustura )
  • Değişmez mi (orijinal dizi değişmeden kalır)
  • Tarayıcınız bunları desteklemiyorsa standart JavaScript işlevleriyle yapın - çoklu dolgu kullanın

Bu kod örneğinde , bir diziden istenmeyen öğeleri kaldırmak için "array.filter (...)" işlevini kullanıyorum. Bu işlev orijinal diziyi değiştirmez ve yeni bir dizi oluşturur. Tarayıcınız bu işlevi desteklemiyorsa (örneğin, sürüm 9'dan önceki Internet Explorer veya sürüm 1.5'ten önce Firefox), Mozilla'dan filtre çoklu dolgusunu kullanmayı düşünün .

Öğe kaldırılıyor (ECMA-262 Edition 5 kodu, eski stil JavaScript)

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 ]

Öğe kaldırılıyor (ECMAScript 6 kodu)

let value = 3

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

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

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

ÖNEMLİ ECMAScript 6 "() => {}" ok işlevi sözdizimi Internet Explorer'da, 45 sürümünden önceki Chrome'da, 22 sürümünden önce Firefox'ta ve 10 sürümünden önce Safari'de desteklenmemektedir. ECMAScript 6 sözdizimini eski tarayıcılarda kullanmak için BabelJS'yi kullanabilirsiniz .


Birden çok öğeyi kaldırma (ECMAScript 7 kodu)

Bu yöntemin ek bir avantajı, birden çok öğeyi kaldırabilmenizdir

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 ]

ÖNEMLİ "array.includes (...)" işlevi Internet Explorer'da, 47 sürümünden önce Chrome, 43 sürümünden önce Firefox, 9 sürümünden önce Safari ve 14 sürümünden önce Edge'de desteklenmemektedir, bu nedenle burada Mozilla'dan çok dolgu vardır .

Birden fazla öğeyi kaldırma (gelecekte, belki de)

"Bu Bağlayıcı Sözdizimi" teklifi kabul edilirse, bunu yapabilirsiniz:

// 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'de kendiniz deneyin :)

Referans


6
ancak bazen öğeyi orijinal diziden (değiştirilemez) kaldırmak istiyoruz, örneğin Açısal 2 * ngFor yönergesinde kullanılan dizi
Ravinder Payal

43
Kabul edilen çözümden daha iyi çünkü bir maçın sadece bir tekrarını varsaymaz ve değişmezlik tercih edilir
Greg

13
filterbüyük bir dizi için çok daha yavaş olmalı?
Nathan

3
Örneklerinizde aynı değişkenin atamasını kullandıysanız değişmezliğin anlamı nedir? :)
mench

12
Bu harika bir cevap. Splice, filtreleme değil mutasyon için özel bir fonksiyondur. filterdaha yavaş performans gösterebilir ancak daha güvenli ve daha iyi bir koddur. Ayrıca, arr.filter((x,i)=>i!==2)
Matthew

449

Boş bir yer tutmak isteyip istemediğinize bağlıdır.

Boş bir yuva istiyorsanız, silme iyidir:

delete array[index];

Bunu yapmazsanız, splice yöntemini kullanmalısınız :

array.splice(index, 1);

Ve bu öğenin değerine ihtiyacınız varsa, döndürülen dizinin öğesini depolayabilirsiniz:

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

Bir sırayla yapmak isterseniz array.pop(), sonuncusu veya array.shift()birincisi için kullanabilirsiniz (ve her ikisi de öğenin değerini de döndürür).

Ve öğenin dizinini bilmiyorsanız, array.indexOf(item)almak için kullanabilirsiniz ( if()bir öğeyi almak için a veya while()hepsini almak için a). array.indexOf(item)dizini ya da bulunmazsa -1 değerini döndürür. 


25
deletebir diziden bir öğe kaldırmak için doğru bir yol değil !!
Progo

16
"Bir boşluğu boşaltmak" için tuşunu kullanın array[index] = undefined;. Kullanmak deleteoptimizasyonu yok edecektir.
Bergi

4
@ Jakub çok iyi bir yorum çünkü çok zaman kaybettiğimi ve uygulama kodumun bir şekilde bozuk olduğunu düşündüğümü anlamak için ...
Pascal

İndexOf'dan ne elde ettiğinizi açıklayan son paragraf gerçekten yardımcı oldu
A. D'Alfonso

277

Bir arkadaşım Internet Explorer 8'de sorunlar yaşıyordu ve bana ne yaptığını gösterdi. Ona bunun yanlış olduğunu söyledim ve yanıtı burada bulduğunu söyledi. Geçerli en iyi yanıt tüm tarayıcılarda (örneğin Internet Explorer 8) çalışmaz ve öğenin yalnızca ilk oluşumunu kaldırır.

Bir diziden TÜM örnekleri kaldır

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

Diziyi geriye doğru döndürür (öğeler kaldırıldıkça dizinler ve uzunluk değişeceğinden) ve bulunursa öğeyi kaldırır. Tüm tarayıcılarda çalışır.


11
@sroes, döngü başlangıç dizininden başladığı i = arr.length -1veya i--maks diziniyle aynı olduğu için olmamalıdır . arr.lengthiçin sadece bir başlangıç ​​değeridir i. eşit olana kadar (gerçek bir değer) ve döngü duruncaya kadar her i--zaman doğrudur (ve her döngüde 1 0azalır).
gmajivu

1
İkinci işlev oldukça verimsizdir. Her yinelemede "indexOf" dizinin başından itibaren aramaya başlayacaktır.
ujeenator

3
@AmberdeBlack, öğenin 1'den fazla yinelemesine sahip bir koleksiyonda , diziyi birden çok kez değiştirme gereksinimini ortadan kaldırarak, filtre yöntemini çağırmak çok daha iyidir arr.filter(function (el) { return el !== item }). Bu biraz daha fazla bellek tüketir, ancak yapılması gereken daha az iş olduğundan daha verimli çalışır.
Eugene Kuzmenko

1
@AlJey, yalnızca IE9 + 'dan kullanılabilir. Hala işe yarama şansı var.
ujeenator

1
Bu cevap benim için çalıştı çünkü kaldırılan birkaç öğeye ihtiyacım vardı, ancak belirli bir sırada değil. Burada for döngüsünün geriye doğru ilerlemesi, öğeleri diziden mükemmel bir şekilde kaldırır.
mintedsky

172

İki ana yaklaşım vardır:

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

  2. sil :delete anArray[index];

Bir dizi için sil komutunu kullanırken dikkatli olun. Nesnelerin niteliklerini silmek için iyidir, ancak diziler için çok iyi değildir. spliceDiziler için kullanmak daha iyidir .

deleteBir dizi için kullandığınızda bunun için yanlış sonuçlar alabileceğinizi unutmayın anArray.length. Başka bir deyişle, deleteöğeyi kaldırır, ancak length özelliğinin değerini güncellemez.

Ayrıca delete komutunu kullandıktan sonra dizin numaralarında delikler olmasını bekleyebilirsiniz; örneğin, index 1, 3, 4, 8, 9 ve 11 dizinlerini ve delete komutunu kullanmadan önceki uzunluğuna sahip olabilirsiniz. Bu durumda, fordizinler artık sıralı olmadığından dizinlenmiş tüm döngüler kilitlenir.

Herhangi bir deletenedenle kullanmak zorunda kalırsanız, for eachdiziler arasında döngü yapmanız gerektiğinde döngüler kullanmalısınız . Aslında, formümkünse her zaman dizinlenmiş döngüler kullanmaktan kaçının . Bu şekilde kod daha sağlam ve dizinlerle ilgili sorunlara daha az eğilimli olacaktır.


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)


14
Bu yaklaşımın büyük bir hayranı değilim. Sonunda farklı kütüphaneler veya çerçeveler kullanırsanız, bunlar birbirleriyle çakışabilir.
Charlie Kilian


10
Bir for indizide bir yapıyorsanız , zaten bir sorununuz var demektir.
Zirak

2
bunu yaparsanız for indiziler üzerinde, zaten büyük sorunlarımız var.
Rainb

Object.defineProperty stackoverflow.com/a/35518127/3779853 kullanın ve hazırsınız.
phil294

105

indexOfVeya kullanımına gerek yoktur splice. Ancak, bir öğenin yalnızca bir örneğini kaldırmak istiyorsanız daha iyi performans gösterir.

Bul ve taşı (taşı):

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

indexOfVe splice(indexof) kullanın :

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

Yalnızca splice(ek yeri) kullanın :

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

1000 elemanlı dizi için düğümlerde çalışma süreleri (ortalama 10000'den fazla çalışma):

indexof yaklaşık olarak 10x yavaştır hareket . Çağrısına kaldırarak geliştirilmiş olsa bile indexOfiçinde ek yeri o çok daha kötü performans gösteren hareket .

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

5
Burada sunulan 'move' yönteminin tüm tarayıcılarda çalışması ve ekstra bir dizi oluşturmaktan kaçınması gibi görünüyor; buradaki diğer çözümlerin çoğunda bu sorunlardan biri veya her ikisi de bulunur. Bence bu "güzel" görünmese bile çok daha fazla oyu hak ediyor.
sockmonk

73

Bu değer yerine bir yüklem sağlar.

NOT: verilen diziyi günceller ve etkilenen satırları döndürür.

kullanım

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

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

Tanım

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

-1 kontrolüne (i> -1) ihtiyacınız olduğunu bilmiyorum. Ayrıca, bu işlevlerin kaldırmaktan çok filtre gibi davrandığını düşünüyorum. Row.id === 5 iletirseniz, yalnızca id 5 olan bir dizi ile sonuçlanır, bu nedenle kaldırma işleminin tersini yapar. ES2015'te güzel görünür: var results = ArrayHelper.remove (myArray, row => row.id === 5);
Ne Olurdu

@WhatWouldBeCool bu işlev orijinal diziyi değiştirir ve sonucu yeni bir diziye kopyalamak yerine kaldırılan öğeyi döndürür
amd

68

Filtre yöntemiyle kolayca yapabilirsiniz :

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

Bu diziden tüm öğeleri kaldırır ve aynı zamanda bir kombinasyonu daha hızlı çalışır sliceve indexOf.


3
Bunun daha hızlı olduğuna dair bir kaynağınız var mı?
user3711421

2
Güzel çözüm. Ama işaret gibi 1 tüm oluşumları kaldıracak beri ama kel olmak önemlidir, bu dilim ve indexOf aynı sonucu vermez
user3711421

1
@ user3711421 Bunun nedeni, yalnızca dilim ve indexOf'un "belirli bir öğeyi kaldırmak için" istediği şeyi yapmamasıdır. Öğeyi yalnızca bir kez kaldırır, bu kaç tane olursa olsun belirli bir öğeyi kaldırır
Salvador Dali

66

John Resig iyi bir uygulama yayınladı :

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

Genel bir nesneyi genişletmek istemiyorsanız, bunun yerine aşağıdakine benzer bir şey yapabilirsiniz:

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

Ancak bunu göndermemin ana nedeni, kullanıcıları bu sayfadaki yorumlarda önerilen alternatif uygulamaya karşı uyarmaktır (14 Aralık 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;
};

İlk başta iyi çalışıyor gibi görünüyor, ancak acı verici bir süreçle bir dizideki ikinci son öğeyi kaldırmaya çalışırken başarısız olduğunu keşfettim. Örneğin, 10 öğeli bir diziniz varsa ve 9. öğeyi bununla kaldırmaya çalışırsanız:

myArray.remove(8);

Sonunda 8 elemanlı bir dizi elde edersiniz. Nedenini bilmiyorum ama John'un orijinal uygulamasında bu sorun olmadığını doğruladım.


Neden Object.prototype.hasOwnPropertyher zaman kullanmanın iyi bir fikir olduğunu zor yoldan öğrendim Dav
Davi Fiamenghi

64

Underscore.js , birden çok tarayıcıyla ilgili sorunları çözmek için kullanılabilir. Varsa, yerleşik tarayıcı yöntemlerini kullanır. Eski Internet Explorer sürümlerinde olduğu gibi yoksa, kendi özel yöntemlerini kullanır.

Diziden öğeleri kaldırmak için basit bir örnek (web sitesinden):

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

zarif ve özlü olsa da, OP açıkça sadece çekirdek
JS'den

64

ES6'yı kullanabilirsiniz. Örneğin, bu durumda '3' değerini silmek için:

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

Çıktı :

["1", "2", "4", "5", "6"]

4
Bu cevap güzel, çünkü orijinali doğrudan değiştirmek yerine orijinal dizinin bir kopyasını oluşturuyor.
Claudio Holanda

Not: Array.prototype.filter ECMAScript 5.1'dir (IE8 yok). daha spesifik çözümler için: stackoverflow.com/a/54390552/8958729
Chang

54

Silinmiş konumların kaldırıldığı yeni bir dizi istiyorsanız, istediğiniz öğeyi her zaman silebilir ve diziyi filtreleyebilirsiniz. Filtre yöntemini uygulamayan tarayıcılar için dizi nesnesinin bir uzantısına ihtiyaç duyabilir , ancak uzun vadede yapmanız gereken tek şey budur:

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

Görüntülenmelidir [1, 2, 3, 4, 6].


45

Bu kodu inceleyin. Her büyük tarayıcıda çalışır .

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

Bu işlevi ara

remove_item(array,value);

4
@RolandIllig Bir for in-loop kullanımı ve betiğin sonucun doğrudan döngüden döndürülmesiyle daha önce durdurulabilmesi hariç . Upvotes makul;)
yckart

1
Bu, küçük diziler için mükemmel bir yaklaşımdır. Her tarayıcıda çalışır, minimal ve sezgisel kod kullanır ve ekstra karmaşık çerçeveler, şimler veya çoklu dolgular olmadan.
Beejor

Ayrıca for( i = 0; i < arr.length; i++ ), tarayıcı öğelerini (ile for in) depolamaya karar verdiği herhangi bir siparişe karşı kesin endeksleri koruduğu için daha iyi bir yaklaşım olacak yckart'ın yorumunu da tekrarlamalıyım . Bunu yapmak, bir değerin dizi dizinini ihtiyacınız varsa almanızı da sağlar.
Beejor

41

Lodash kullanabilirsiniz _.pull (diziyi değiştir), _.pullAt (diziyi değiştir) veya _.without (diziyi değiştirmez),

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

2
Bu OP'nin istediği çekirdek JS değil, değil mi?
-

12
@ some-descript-user Haklısınız. Ancak benim gibi birçok kullanıcı, sadece OP için değil, genel bir cevap aramaya geliyor.
Chun Yang

@ChunYang Kesinlikle haklısın. Zaten lodash kullanıyorum, neden sadece zaman kazandırırsa kullanmıyorsunuz?
int-i

38

ES6 ve mutasyon olmadan: (Ekim 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)


Neden sadece filtero zaman kullanmıyorsunuz ? array.filter((_, index) => index !== removedIndex);.
user4642212

@ user4642212 haklısın! Ayrıca, Golang stilinin alt
çizgisini beğendim

36

Bir diziden belirli bir öğeyi / dizeyi kaldırmak tek bir astarda yapılabilir:

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

nerede:

theArray : belirli bir şeyi kaldırmak istediğiniz dizi

stringToRemoveFromArray : kaldırılmasını istediğiniz dize ve 1, kaldırmak istediğiniz öğelerin miktarıdır.

NOT : "stringToRemoveFromArray" dizininizde bulunmuyorsa, dizinin son öğesini kaldırır.

Öğeyi kaldırmadan önce dizinizde var olup olmadığını kontrol etmek her zaman iyi bir uygulamadır.

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

İstemcinizin bilgisayarlarındaki daha yeni Ecmascript sürümlerine erişiminiz varsa (UYARI, eski istasyonlarda çalışmayabilir):

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

Burada '3' diziden kaldırılmasını istediğiniz değerdir. Dizi daha sonra:['1','2','4','5','6']


Bu, radyo düğmesi geçişine dayalı bir diziyi güncellemeye çalışırken benim için çalışan cevaptır.
jdavid05

4
Dikkat edin, "stringToRemoveFromArray"dizinizde bulunmuyorsa, dizinin son öğesini kaldırır.
Füzyon

35

JavaScript kullanarak bir diziden bir öğeyi kaldırmanın birkaç yolu .

Açıklanan tüm yöntem orijinal diziyi değiştirmez ve bunun yerine yeni bir oluşturur.

Bir öğenin dizinini biliyorsanız

Bir diziniz olduğunu ve konumdaki bir öğeyi kaldırmak istediğinizi varsayalım i.

Bir yöntem kullanmaktır 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()aldığı dizinlerle yeni bir dizi oluşturur. Baştan kaldırmak istediğimiz dizine kadar yeni bir dizi oluştururuz ve kaldırdığımız diziden sonraki ilk konumdan dizinin sonuna kadar başka bir diziyi birleştiririz.

Değeri biliyorsanız

Bu durumda, filter()daha bildirimsel bir yaklaşım sunan iyi bir seçenek kullanmaktır :

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

console.log(filteredItems)

ES6 ok işlevlerini kullanır. Eski tarayıcıları desteklemek için geleneksel işlevleri kullanabilirsiniz:

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

console.log(filteredItems)

veya Babel'i kullanabilir ve eski tarayıcılar için daha sindirilebilir hale getirmek için ES6 kodunu ES5'e geri aktarabilir, ancak kodunuza modern JavaScript yazabilirsiniz.

Birden çok öğeyi kaldırma

Tek bir öğe yerine birçok öğeyi kaldırmak isterseniz ne olur?

En basit çözümü bulalım.

Dizine göre

Sadece bir işlev oluşturabilir ve serideki öğeleri kaldırabilirsiniz:

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)

Değere göre

Geri arama işlevinin içine dahil edilmesini arayabilirsiniz:

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)

Orijinal diziyi değiştirmekten kaçının

splice()(karıştırılmamalıdır slice()) orijinal diziyi değiştirir ve bundan kaçınılmalıdır.

(aslen https://flaviocopes.com/how-to-remove-item-from-array/ adresinde yayınlanmıştır )


34

Tamam, örneğin aşağıdaki diziye sahipsiniz:

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

Ve biz 4 sayısını silmek istiyoruz. Sadece aşağıdaki kodu kullanabilirsiniz:

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

Bu işlevi yeniden kullanıyorsanız, aşağıdaki gibi yerel dizi işlevine eklenecek yeniden kullanılabilir bir işlev yazarsınız :

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

Peki, dizide birkaç [5] s ile aşağıdaki diziye sahipseniz ne olur?

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

Hepsini kontrol etmek için bir döngüye ihtiyacımız var, ancak yerleşik JavaScript işlevlerini kullanmak için daha kolay ve daha verimli bir yol olduğundan, bunun yerine aşağıdaki gibi bir filtre kullanan bir işlev yazıyoruz:

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]

Ayrıca, Lodash veya Undercore gibi, bunu yapmanıza yardımcı olan üçüncü taraf kütüphaneleri de vardır. Daha fazla bilgi için bkz. Lodash _.pull, _.pullAt veya _.without.


Küçük bir yazım hatası var. Lütfen düzeltin. this.splice(num.indexOf(x), 1);=>this.splice(this.indexOf(x), 1);
TheGwa

Lütfen JavaScript'te yerleşikleri artırmayın (Array.prototype işlevlerini ekleyin). Bu yaygın olarak kötü uygulama olarak kabul edilmektedir.
aikeru

Katılıyorum, bu dünyada yapılacak en iyi şey değil, ama bu durumda nasıl fonksiyona aktarabilirsiniz?
Alireza

Dizini kontrol etmelisiniz. Dizin = -1 ise, ekleme (-1,1) son öğeyi kaldıracaktır
Richard Chan

29

JavaScript için oldukça yeniyim ve bu işlevselliğe ihtiyacım vardı. Ben sadece şunu yazdım:

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

Sonra kullanmak istediğinizde:

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

Çıktı - Beklendiği gibi. ["item1", "item1"]

Benden farklı ihtiyaçlarınız olabilir, bu yüzden onlara uyacak şekilde kolayca değiştirebilirsiniz. Umarım bu birine yardımcı olur.


1
Diziniz gerçekten uzunsa ve içinde öğenin birkaç örneği varsa, bu korkunç bir davranış olacaktır. Dizinin indexOf yöntemi her seferinde başlangıçta başlar, dolayısıyla maliyetiniz O (n ^ 2) olur.
Zag


27

Dizide karmaşık nesneleriniz varsa filtreleri kullanabilirsiniz? $ .İnArray veya array.splice öğesinin kullanımı o kadar kolay değildir. Özellikle nesneler dizide belki de sığsa.

Örneğin, Kimlik alanına sahip bir nesneniz varsa ve nesnenin bir diziden kaldırılmasını istiyorsanız:

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

Ben böyle yapmayı seviyorum. Bir ok fonksiyonu kullanarak, bir astar olabilir. Performansı merak ediyorum. Ayrıca bu dizi yerine hiçbir şey değer . Eski diziye başvurusu olan hiçbir kod değişikliği fark etmez.
joeytwiddle

27

ECMAScript 6'ya göre cevap vermek istiyorum . Aşağıdaki gibi bir diziniz olduğunu varsayın:

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

Gibi özel bir dizinde silmek istiyorsanız 2, aşağıdaki kodu yazın:

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

Ancak, gibi özel bir öğeyi silmek istiyorsanız 3ve dizinini bilmiyorsanız, aşağıdakileri yapın:

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

İpucu : boş bir dizi elde etmediğiniz sürece lütfen filtre geri araması için bir ok işlevi kullanın.


25

Güncelleme: Bu yöntem yalnızca ECMAScript 2015'i (eski adıyla ES6) kullanamıyorsanız önerilir. Kullanabiliyorsanız, buradaki diğer cevaplar çok daha temiz uygulamalar sağlar.


Buradaki özgeçmiş sorununuzu çözecek ve aynı zamanda argümanın sadece 1 (veya belirtilen bir değer) yerine tüm oluşumlarını silecektir.

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

Kullanımı:

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]

25

Verim

Bugün (2019-12-09) Seçilen çözümler için macOS v10.13.6 (High Sierra) üzerinde performans testleri yürütüyorum. Ben delete(A) göstermek , ama diğer yöntemlerle karşılaştırıldığında kullanmıyorum, çünkü dizi boş alan bıraktı.

Sonuçlar

  • en hızlı çözüm array.splice(C) 'dir (ikinci kez bulunduğu küçük diziler için Safari hariç)
  • büyük diziler için, array.slice+splice(H) Firefox ve Safari için en hızlı değişmez çözümdür; Array.from(B) Chrome'da en hızlı
  • değişebilen çözeltiler genellikle değişmezden 1.5x-6x daha hızlıdır
  • Safari'deki küçük masalar için şaşırtıcı bir şekilde değişebilir çözelti (C) değişmez çözeltiden (G) daha yavaştır

ayrıntılar

Testlerde orta elemanı diziden farklı şekillerde kaldırırım. A, C, çözeltiler yerinde bulunmaktadır. B, D, E, F, G, H çözeltileri değişken değildir.

10 elemanlı dizi sonuçları

Resim açıklamasını buraya girin

Chrome'da array.splice(C) en hızlı yerinde çözümdür. array.filter(D) en hızlı değişmez bir çözümdür. En yavaş array.slice(F). Testi makinenizde buradan yapabilirsiniz .

1.000.000 element içeren dizi sonuçları

Resim açıklamasını buraya girin

Chrome'da array.splice(C) en hızlı yerinde çözümdür ( delete(C) benzer hızlıdır - ancak dizide boş bir yuva bırakmıştır (bu nedenle 'tam kaldırma' gerçekleştirmez)). array.slice-splice(H) en hızlı değişmez bir çözümdür. En yavaş array.filter(D ve E). Testi makinenizde buradan yapabilirsiniz .

Tarayıcılar için karşılaştırma: Chrome v78.0.0, Safari v13.0.4 ve Firefox v71.0.0

Resim açıklamasını buraya girin


24

Dizinizi asla değiştirmemelisiniz. Bu fonksiyonel programlama modeline aykırıdır. ECMAScript 6 yöntemini kullanarak verilerini değiştirmek istediğiniz diziye başvurmadan yeni bir dizi oluşturabilirsiniz filter;

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

Diziden kaldırmak istediğinizi varsayalım 5, bunu şu şekilde yapabilirsiniz:

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

Bu, kaldırmak istediğiniz değer olmadan yeni bir dizi verecektir. Sonuç şu olacaktır:

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

Daha fazla bilgi için Array.filter'daki MDN belgelerini okuyabilirsiniz .


21

Daha modern, ECMAScript 2015 (eski adıyla Harmony veya ES 6) yaklaşımı. Verilen:

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

Sonra:

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

Verim:

[1, 2, 4]

Sen kullanabilirsiniz Babel ve polyfill hizmeti bu iyi tarayıcılarda desteklenir sağlamak için.


4
.filterÖğenin aynı diziden kaldırılmasıyla tam olarak aynı olmayan yeni bir dizi döndürdüğünü unutmayın . Bu yaklaşımın yararı dizi yöntemlerini birlikte zincirleyebilmenizdir. örneğin:[1,2,3].filter(n => n%2).map(n => n*n) === [ 1, 9 ]
CodeOcelot

Harika, eğer dizide 600k elementim varsa ve ilk 50k'yi kaldırmak istiyorsanız, bu yavaşlığı hayal edebiliyor musunuz? Bu çözüm değildir, sadece elemanları kaldıran ve hiçbir şey döndürmeyen fonksiyona ihtiyaç vardır.
dev1223

@Seraph Bunun için muhtemelen spliceveya kullanmak istersiniz slice.
bjfletcher

@bjfletcher Bu daha da iyisi, kaldırma işlemi sırasında sadece 50K eleman ayırın ve bir yere atın. (dilim 550K elemanları ile, ancak pencereden atmadan).
dev1223

Ben bjfletcher'ın cevabını tercih ederim, ki bu kadar kısa olabilir items= items.filter(x=>x!=3). Ayrıca, OP büyük veri seti için herhangi bir gereklilik belirtmedi.
runsun

21

Dizide 1'den 9'a kadar var ve 5'i kaldırmak istiyorsunuz. Aşağıdaki kodu kullanın:

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


Birden çok değer istiyorsanız. Örnek: - 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);


Bir dizideki dizi değerini kaldırmak istiyorsanız. Örnek: [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);

Desteklenen tarayıcı bağlantısı içerir .


19

Halihazırda birçok cevap olduğunu biliyorum, ancak birçoğu sorunu aşırı derecede karmaşıklaştırıyor gibi görünüyor. İşte bir anahtarın tüm örneklerini kaldırmanın basit, özyinelemeli bir yolu - dizin bulunana kadar kendini çağırır. Evet, yalnızca tarayıcılarda çalışır indexOf, ancak basittir ve kolayca çoklu doldurulabilir.

Bağımsız işlev

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

    if(index === -1) return;

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

Prototip yöntemi

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

    if(index === -1) return;

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

Sadece bir not, bu yöntemle 1 uyarı yığın taşma potansiyeli. Büyük dizilerle çalışmadığınız sürece bir sorun yaşamamalısınız.
wharding28

Ama neden ortada bir dönüş? Bu etkili bir şekilde bir ifadedir.
Peter Mortensen

18

Öğenin birden çok örneği varsa, dizinleri vidalamamak için geriye doğru bir döngü yapabilirsiniz.

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

Canlı Demo

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.