सवाल मैं जावास्क्रिप्ट में किसी सरणी से किसी विशेष तत्व को कैसे हटा सकता हूं?


मेरे पास पूर्णांक की एक सरणी है, और मैं इसका उपयोग कर रहा हूं .push() इसमें तत्व जोड़ने के लिए विधि।

क्या किसी सरणी से विशिष्ट तत्व को निकालने का कोई आसान तरीका है? कुछ के बराबर array.remove(int);

मुझे उपयोग करना है कोर जावास्क्रिप्ट - नहीं ढांचे की अनुमति है।


6131
2018-04-23 22:17


मूल


अगर आपको समर्थन करने की ज़रूरत है <IE9 (आह) तो जाँच यह SO सवाल है के बारे में indexOf आईई में - Scotty.NET
(lodash) सरणी = ['ए', 'बी', 'सी']; _.pull (सरणी, 'ए') // सरणी => ['बी', 'सी']; यह भी देखें stackoverflow.com/questions/5767325/... - Chun Yang
फिल्टर विधि आप जो चाहते हैं वह कर सकते हैं। - Salvador Dali
आप डिलीट का उपयोग कर सकते हैं लेकिन यह इंडेक्स को फिर से व्यवस्थित नहीं करेगा बल्कि यह इस स्लॉट को 'अपरिभाषित × 1' पर सेट करेगा। उदाहरण के लिए: var list = [1,2,3,4,5,6] -> सूची हटाएं [1] -> [1, अपरिभाषित × 1, 3, 4, 5, 6]। - DevWL
यहां दो प्रमुख संभावनाओं का प्रदर्शन बेंचमार्क: jsben.ch/#/b4Ume - EscapeNetscape


जवाब:


खोजो index उस सरणी तत्व का जिसे आप निकालना चाहते हैं, उसके बाद उस अनुक्रमणिका को हटा दें splice

Splice () विधि हटाकर एक सरणी की सामग्री को बदलती है   मौजूदा तत्व और / या नए तत्व जोड़ना।

var array = [2, 5, 9];
var index = array.indexOf(5);
if (index > -1) {
  array.splice(index, 1);
}
// array = [2, 9]

का दूसरा पैरामीटर splice निकालने के लिए तत्वों की संख्या है। ध्यान दें कि splice सरणी को जगह में संशोधित करता है और हटाए गए तत्वों वाली एक नई सरणी देता है।


ध्यान दें: indexOf के लिए ब्राउज़र समर्थन सीमित है


8923
2018-04-23 22:23



@ पीटर, हाँ आप सही हो सकते हैं। यह आलेख अधिक बताता है और असंगत ब्राउज़रों के लिए एक समाधान है: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/... - Tom Wadley
खतरनाक! यदि आप गतिशील मानों के साथ काम कर रहे हैं (सरणी से गतिशील मान जोड़ें और हटाएं) और मान सरणी में मौजूद नहीं है (अनुक्रमणिका बनें -1) उपर्युक्त कोड सरणी के अंतिम तत्व को हटा देगा। - Adrian P.
@AlexandreWiechersVaz बेशक यह आदेश को संरक्षित करता है, अगर ऐसा नहीं होता तो यह बिल्कुल बेकार होगा - TheZ
आप कोड सहित आईई ब्राउज़र समर्थन समस्या को दूर कर सकते हैं यहां दिया गया
@AdrianP। array.indexOf(testValue) खाली सरणी पर -1 होगा, और यदि आप इसके लिए परीक्षण कर रहे हैं तो कोई splice। शायद जवाब बदल गया है। - UpTheCreek


मुझे नहीं पता कि आप कैसे उम्मीद कर रहे हैं 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];

896
2018-04-23 22:20



delete एक सरणी से तत्व को हटाने का सही तरीका नहीं है! - Felix Kling
@ फ़ेलिक्सक्लिंग यह निर्भर करता है, अगर आप इसे बनाना चाहते हैं तो यह काम करता है array.hasOwnProperty(i) रिटर्न false और उस स्थिति पर तत्व है undefined। लेकिन मैं स्वीकार करूंगा कि ऐसा करना बहुत आम बात नहीं है। - Peter Olson
delete सरणी की लंबाई को अपडेट नहीं करेगा और न ही तत्व को मिटा देता है, केवल इसे विशेष मान के साथ बदल देता है undefined। - diosney
@ डिओसनी मुझे नहीं पता कि आपका मतलब क्या है जब आप कहते हैं कि यह वास्तव में तत्व को मिटा नहीं देता है। इसके अलावा, यह उस इंडेक्स पर मूल्य को प्रतिस्थापित करने से कहीं अधिक है undefined: यह सरणी से सूचकांक और मूल्य दोनों को हटा देता है, यानी बाद में delete array[0], "0" in array झूठी वापसी होगी। - Peter Olson
यदि आप नामित गुणों से निपट रहे हैं तो हटाएं एक अच्छा तंत्र है var array=[];array['red']=1;array['green']=2;array['blue']=3;delete array['green']; - Jefferey Cave


2016 अक्टूबर को संपादित किया गया

  • यह सरल, सहज और स्पष्ट करें (https://en.wikipedia.org/wiki/Occam%27s_razor)
  • इसे अपरिवर्तनीय करें (मूल सरणी अपरिवर्तित रहें)
  • मानक जेएस फ़ंक्शंस के साथ ऐसा करें, यदि आपका ब्राउज़र उनका समर्थन नहीं करता है - पॉलीफिल का प्रयोग करें

इस कोड उदाहरण में मैं उपयोग करता हूं "Array.filter (...)" सरणी से अवांछित वस्तुओं को हटाने के लिए फ़ंक्शन, यह फ़ंक्शन मूल सरणी को नहीं बदलता है और एक नया बनाता है। यदि आपका ब्राउज़र इस फ़ंक्शन का समर्थन नहीं करता है (उदाहरण के लिए संस्करण 9 से पहले IE, या संस्करण 1.5 से पहले फ़ायरफ़ॉक्स), तो उपयोग करने पर विचार करें मोज़िला से फ़िल्टर पॉलीफिल

आइटम को हटाने (ईसीएमए -262 संस्करण 5 कोड उर्फ ​​पुरानी जेएस)

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 में बिल्कुल समर्थित नहीं है, 45 संस्करण से पहले क्रोम, 22 संस्करण से पहले फ़ायरफ़ॉक्स, 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 ]

जरूरी "array.includes (...)" फ़ंक्शन को IE में बिल्कुल समर्थित नहीं है, 47 संस्करण से पहले क्रोम, 43 संस्करण से पहले फ़ायरफ़ॉक्स, 9 संस्करण से पहले सफारी और 14 संस्करण से पहले एज मोज़िला से पॉलीफिल यहां है

कई वस्तुओं को हटा रहा है (कटिंग-एज प्रयोगात्मक जावास्क्रिप्ट 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 में इसे स्वयं आज़माएं :)

संदर्भ


678
2017-12-19 19:54



लेकिन, कभी-कभी हम मूल सरणी (गैर अपरिवर्तनीय) से तत्व को हटाना चाहते हैं, उदाहरण के लिए कोणीय 2 * ngFor निर्देश में प्रयोग किया जाने वाला सरणी - Ravinder Payal
स्वीकार किए गए समाधान से बेहतर क्योंकि यह एक मैच की केवल एक घटना नहीं मानता है और अपरिवर्तनीयता बेहतर है - Greg
फ़िल्टर का उपयोग splice का उपयोग करने से बहुत अच्छा है। बहुत आसान। - user3344977
filter हालांकि एक बड़ी सरणी के लिए बहुत धीमी होनी चाहिए? - Nathan
सुपर धीमी विधि। - highmaintenance


इस पर निर्भर करता है कि आप खाली जगह रखना चाहते हैं या नहीं।

यदि आप एक खाली स्लॉट चाहते हैं, तो हटाएं ठीक है:

delete array[ index ];

यदि आप नहीं करते हैं, तो आपको इसका उपयोग करना चाहिए ब्याह तरीका:

array.splice( index, 1 );

और यदि आपको उस आइटम के मान की आवश्यकता है, तो आप केवल लौटे सरणी के तत्व को स्टोर कर सकते हैं:

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

यदि आप इसे किसी क्रम में करना चाहते हैं, तो आप इसका उपयोग कर सकते हैं array.pop() आखिरी एक या के लिए array.shift() पहले के लिए (और दोनों आइटम के मूल्य भी वापस)।

और यदि आप आइटम की अनुक्रमणिका नहीं जानते हैं, तो आप इसका उपयोग कर सकते हैं array.indexOf( item ) इसे पाने के लिए (ए में if() एक आइटम या एक में पाने के लिए while() उन सभी को पाने के लिए)। array.indexOf( item ) अगर नहीं मिला तो सूचकांक या -1 देता है।


359
2018-04-23 22:32



यह ध्यान देने योग्य है var valueहटाए गए मान को स्टोर नहीं करेगा लेकिन हटाए गए मान वाले सरणी को नहीं रखा जाएगा। - Jakub
delete एक सरणी से तत्व को हटाने का सही तरीका नहीं है !! - Progo
यदि आप "स्लॉट खाली करना" चाहते हैं, तो इसका उपयोग करें array[index] = undefined;। का उपयोग करते हुए delete अनुकूलन को नष्ट कर देगा। - Bergi
@Jakub बहुत अच्छी टिप्पणी क्योंकि यह समझने के लिए कि मैंने बहुत समय खो दिया और सोचा कि मेरा आवेदन कोड किसी तरह टूटा हुआ है ... - Pascal


एक दोस्त में समस्याएं थीं इंटरनेट एक्सप्लोरर 8, और मुझे दिखाया कि उसने क्या किया। मैंने उससे कहा कि यह गलत था, और उसने मुझे बताया कि उसे यहां जवाब मिला है। वर्तमान शीर्ष उत्तर सभी ब्राउज़रों (उदाहरण के लिए इंटरनेट एक्सप्लोरर 8) में काम नहीं करेगा, और यह केवल आइटम की पहली घटना को हटा देगा।

एक सरणी से सभी उदाहरण निकालें

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

यह पीछे की ओर सरणी के माध्यम से loops (चूंकि वस्तुओं को हटा दिया जाता है के रूप में सूचकांक और लंबाई बदल जाएगा) और अगर यह पाया जाता है तो आइटम को हटा देता है। यह सभी ब्राउज़रों में काम करता है।


228
2017-08-10 19:21



@sroes यह नहीं होना चाहिए क्योंकि लूप शुरू होता है i = arr.length -1 या i-- इसे अधिकतम सूचकांक के समान बनाते हैं। arr.length के लिए सिर्फ एक प्रारंभिक मूल्य है i। i-- हमेशा रहूंगा truthy (और प्रत्येक लूप सेशन में 1 से कम करके) जब तक यह बराबर नहीं होता है 0 (एक झूठा मूल्य) और लूप तब बंद हो जाएगा। - gabeno
दूसरा कार्य बल्कि अक्षम है। प्रत्येक पुनरावृत्ति पर "indexOf" सरणी की शुरुआत से खोज शुरू कर देगा। - Ujeenator
@AmberdeBlack, एक संग्रह पर 1 से अधिक घटनाओं के साथ मद, इसे कॉल करना बेहतर है फिल्टर इसके बजाय विधि arr.filter(function (el) { return el !== item }), कई बार सरणी को म्यूट करने की आवश्यकता से परहेज करें। यह थोड़ा अधिक स्मृति का उपभोग करता है, लेकिन अधिक कुशलता से संचालित होता है, क्योंकि कम काम करने की आवश्यकता होती है। - Eugene Kuzmenko
@AlJey, यह केवल IE9 + से उपलब्ध है। अभी भी एक मौका है कि यह काम नहीं करेगा। - Ujeenator
यह जवाब मेरे लिए काम करता था क्योंकि मुझे कई वस्तुओं को हटा दिया गया था लेकिन किसी भी विशेष क्रम में नहीं। लूप के पीछे की प्रगति यहां सरणी से वस्तुओं को पूरी तरह से हटा देती है। - mintedsky


दो प्रमुख दृष्टिकोण हैं:

  1. ब्याह (): anArray.splice(index, 1);

  2. हटाना: delete anArray[index];

जब आप किसी सरणी के लिए डिलीट का उपयोग करते हैं तो सावधान रहें। ऑब्जेक्ट्स के गुणों को हटाने के लिए यह अच्छा है लेकिन सरणी के लिए इतना अच्छा नहीं है। इसका उपयोग करना बेहतर है splice सरणी के लिए।

ध्यान रखें कि जब आप उपयोग करते हैं delete एक सरणी के लिए आप के लिए गलत परिणाम मिल सकता है anArray.length। दूसरे शब्दों में, delete तत्व को हटा देगा लेकिन लंबाई संपत्ति के मूल्य को अपडेट नहीं करेगा।

आप डिलीट का उपयोग करने के बाद इंडेक्स नंबरों में छेद भी प्राप्त कर सकते हैं, उदा। आप इंडेक्स 1,3,4,8,9,11 और लम्बाई के साथ समाप्त हो सकते हैं क्योंकि यह डिलीट का उपयोग करने से पहले था। उस मामले में, सभी अनुक्रमित for लूप दुर्घटनाग्रस्त हो जाएंगे, क्योंकि इंडेक्स अब अनुक्रमिक नहीं हैं।

अगर आपको उपयोग करने के लिए मजबूर किया जाता है delete किसी कारण से, आपको उपयोग करना चाहिए for each loops जब आप सरणी के माध्यम से लूप की जरूरत है। वास्तव में, यदि संभव हो तो हमेशा लूप के लिए अनुक्रमित का उपयोग करने से बचें। इस तरह कोड अधिक मजबूत और इंडेक्स के साथ समस्याओं के लिए कम प्रवण होगा।


131
2017-12-21 11:32





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)


104
2018-04-23 22:20



मैं इस दृष्टिकोण का बड़ा प्रशंसक नहीं हूं। यदि आप अलग-अलग पुस्तकालयों या ढांचे का उपयोग करते हैं, तो वे एक-दूसरे के साथ विवाद कर सकते हैं। - Charlie Kilian
यह भी काम करता है, हालांकि मैंने अंत में इंडेक्सऑफ फ़ंक्शन के साथ जाना चुना। सहायता के लिए धन्यवाद! - Walker
बुरा विचार, इस पोस्ट को देखें: stackoverflow.com/questions/948358/array-prototype-problem - MMeah
यदि आप कर रहे हैं for in एक सरणी पर, आप पहले से ही एक समस्या है। - Zirak
यदि तुम करो for in सरणी पर, आपको पहले से ही बड़ी समस्याएं हैं। - Rainb


उपयोग करने की कोई जरूरत नहीं है indexOf या splice। हालांकि, यह बेहतर प्रदर्शन करता है यदि आप केवल तत्व की एक घटना को हटाना चाहते हैं।

ढूंढें और स्थानांतरित करें (स्थानांतरित करें):

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

उपयोग indexOf तथा splice (के सूचकांक):

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

सिर्फ इस्तमाल करे splice (जोड़):

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

1000 तत्वों (10000 से अधिक रनों के औसत) के साथ सरणी के लिए नोडजेज़ पर रन-टाइम:

के सूचकांक लगभग 10x धीमी है चाल। यहां तक ​​कि अगर कॉल को हटाकर सुधार हुआ है indexOf में ब्याह यह से भी बदतर प्रदर्शन करता है चाल

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

82
2017-09-19 01:53



ऐसा लगता है कि यहां प्रस्तुत 'चाल' विधि को सभी ब्राउज़रों में काम करना चाहिए, और अतिरिक्त सरणी बनाने से बचा जाना चाहिए; यहां अधिकांश अन्य समाधानों में से एक या दोनों समस्याएं हैं। मुझे लगता है कि यह बहुत अधिक वोटों के हकदार है, भले ही यह "सुंदर" जैसा न लगे। - sockmonk


जवाब देने के लिए बहुत पुराना है, लेकिन यह किसी मूल्य की बजाय भविष्यवाणी प्रदान करके किसी की सहायता कर सकता है।

ध्यान दें: यह दिए गए सरणी को अपडेट करेगा, और प्रभावित पंक्तियों को वापस करेगा

प्रयोग

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

56
2018-05-02 12:00



मुझे नहीं पता कि आपको -1 चेक (i> -1) की आवश्यकता है। साथ ही, मुझे लगता है कि ये फ़ंक्शन निकालने से फ़िल्टर की तरह अधिक कार्य करते हैं। यदि आप row.id === 5 पास करते हैं, तो इसके परिणामस्वरूप केवल आईडी 5 के साथ एक सरणी होगी, इसलिए यह निकालने के विपरीत कर रहा है। यह ES2015 में अच्छा लगेगा: var परिणाम = ArrayHelper.remove (myArray, row => row.id === 5); - What Would Be Cool
@WhatWouldBeCool यह फ़ंक्शन मूल सरणी को संशोधित करता है, और परिणाम को एक नई सरणी में कॉपी करने के बजाय हटाए गए आइटम को वापस कर देता है - amd


जॉन रेजिग एक अच्छा कार्यान्वयन पोस्ट किया:

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

लेकिन मैं इसे पोस्ट करने का मुख्य कारण उपयोगकर्ताओं को उस पृष्ठ पर टिप्पणियों में सुझाए गए वैकल्पिक कार्यान्वयन के खिलाफ चेतावनी देना है (14 दिसंबर, 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;
};

ऐसा लगता है कि पहले अच्छी तरह से काम करना प्रतीत होता है, लेकिन एक दर्दनाक प्रक्रिया के माध्यम से मैंने पाया कि यह किसी सरणी में अंतिम तत्व को दूसरे को हटाने का प्रयास करते समय विफल रहता है। उदाहरण के लिए, यदि आपके पास 10-तत्व सरणी है और आप इसके साथ 9वीं तत्व को हटाने का प्रयास करते हैं:

myArray.remove(8);

आप 8-तत्व सरणी के साथ समाप्त होते हैं। पता नहीं क्यों, लेकिन मैंने पुष्टि की कि जॉन के मूल कार्यान्वयन में यह समस्या नहीं है।


53
2017-08-30 19:07



बस कड़ी मेहनत से सीखा कि इसका उपयोग करना एक अच्छा विचार क्यों है Object.prototype.hasOwnProperty हमेशा - Davi Fiamenghi