मैं एक जावास्क्रिप्ट साहचर्य सरणी से वस्तुओं को कैसे निकालूँ?


618

मान लीजिए कि मेरे पास यह कोड है:

var myArray = new Object();
myArray["firstname"] = "Bob";
myArray["lastname"] = "Smith";
myArray["age"] = 25;

अब अगर मैं "lastname" को हटाना चाहता था? .... क्या कुछ समान है
myArray["lastname"].remove()?

(मुझे तत्व की आवश्यकता है क्योंकि तत्वों की संख्या महत्वपूर्ण है और मैं चीजों को साफ रखना चाहता हूं।)


27
एक टिप: सरणियों और नक्शे को भ्रमित न करें। कुछ भाषाएँ, जैसे php, में दोनों के लिए एक ही वस्तु है। यद्यपि आपने यहां सही प्रकार (नई वस्तु ()) का उपयोग किया है, आपने इसे मायएयर्रे नाम दिया है, यह केवल एक लैंग्वेजेज के मानकों का मामला है।
जुआन मेंडेस

यह मत भूलो कि जावास्क्रिप्ट टाइप-कम है और सब कुछ एक वस्तु है। नीचे शाऊल का उत्तर देखें।
15:12

4
@StephanKristyn - सटीक होने के लिए, जेएस के प्रकार हैं लेकिन एक गतिशील और कमजोर तरीके से। उदाहरण के लिए, जबकि इसके चर वास्तव में टाइपलेस हैं, उनके मूल्य नहीं हैं। वह गतिशील हिस्सा है। कमजोर यह दर्शाता है कि विभिन्न मूल्य प्रकारों के बीच संचालन को कड़ाई से परिभाषित नहीं किया गया है और पीछे के रूपांतरणों पर भरोसा करते हैं; उदाहरण के "Test" + {};लिए एक पूरी तरह से वैध जेएस बयान है।
शाऊल

जवाबों:


1134

जावास्क्रिप्ट में वस्तुओं को साहचर्य सरणियों के रूप में माना जा सकता है, मानों के लिए चाबियाँ (गुण) मैपिंग।

जावास्क्रिप्ट में किसी ऑब्जेक्ट से किसी प्रॉपर्टी को निकालने के लिए आप deleteऑपरेटर का उपयोग करते हैं :

const o = { lastName: 'foo' }
o.hasOwnProperty('lastName') // true
delete o['lastName']
o.hasOwnProperty('lastName') // false

ध्यान दें कि जब deleteकिसी के अनुक्रमणिका गुण पर लागू किया जाता है Array, तो आप एक बेहद आबादी वाला सरणी बनाएंगे (जैसे कि एक लापता सूचकांक के साथ एक सरणी)।

के उदाहरणों के साथ काम करते समय Array, यदि आप एक बहुत आबादी वाला सरणी नहीं बनाना चाहते हैं - और आप आमतौर पर नहीं करते हैं - तो आपको इसका उपयोग करना चाहिए Array#spliceया Array#pop

ध्यान दें कि deleteजावास्क्रिप्ट में ऑपरेटर सीधे मेमोरी को फ्री नहीं करता है। इसका उद्देश्य वस्तुओं से गुणों को निकालना है। बेशक, यदि नष्ट की जा रही संपत्ति किसी वस्तु का एकमात्र शेष संदर्भ रखती है o, तो oबाद में सामान्य तरीके से कचरा एकत्र किया जाएगा।

deleteऑपरेटर का उपयोग कोड को अनुकूलित करने के लिए जावास्क्रिप्ट इंजन की क्षमता को प्रभावित कर सकता है ।


18
यदि किसी मौजूदा तत्व को निकालने के लिए ऐरे ऑब्जेक्ट उदाहरण पर उपयोग किया जाता है, तो यह समस्या पैदा करेगा delete myArray[0]Stackoverflow.com/a/9973592/426379 और सरणी तत्वों
शाऊल

4
क्या समस्याएं होंगी?
गोटोक्स

26
@ गोटोक्स - lengthएक ऐरे ऑब्जेक्ट की संपत्ति अपरिवर्तित रहती है।
शाऊल

12
@ सैल: ऐसी समस्याएँ होंगी जो अगर myArrayवास्तव में एक सरणी के रूप में इस्तेमाल की जाती हैं - लेकिन यह ( myArrayदुर्भाग्यपूर्ण नाम नहीं है), यह एक वस्तु है। तो इस मामले deleteमें ठीक है। ध्यान दें कि भले ही इसे new Array()साहचर्य सरणी के रूप में बनाया और इस्तेमाल किया गया हो फिर भी यह ठीक रहेगा। यदि कोई वास्तविक सरणियों का उपयोग कर रहा है, तो आपकी चेतावनी के बारे में अभी भी कुछ जानना बाकी है।
जॉन्डोडो

2
@ जोहंदोदो - सच। यही कारण है कि मैंने अपनी प्रारंभिक टिप्पणी इसी के साथ शुरू की है अगर यह एक ऐरे ऑब्जेक्ट ऑब्जेक्ट पर उपयोग किया जाता है । मैं फिर भी एक दृष्टिकोण पसंद करता हूं जो सभी मामलों में सही ढंग से करता है, नीचे मेरा जवाब देखें।
शाऊल

79

जावास्क्रिप्ट में सभी वस्तुओं को हैशटेबल्स / साहचर्य सरणियों के रूप में लागू किया जाता है। तो, निम्नलिखित बराबर हैं:

alert(myObj["SomeProperty"]);
alert(myObj.SomeProperty);

और, जैसा कि पहले ही संकेत दिया गया है, आप deleteकीवर्ड के माध्यम से किसी ऑब्जेक्ट से एक संपत्ति को "हटा" देते हैं , जिसे आप दो तरीकों से उपयोग कर सकते हैं:

delete myObj["SomeProperty"];
delete myObj.SomeProperty;

आशा है कि अतिरिक्त जानकारी मदद करती है ...


10
ध्यान दिया जाना चाहिए कि यदि संपत्ति एक साधारण शब्द नहीं है, तो डॉट नोटेशन काम नहीं करता है। यानी myObj['some;property']काम करता है, लेकिन myObj.some;propertyनहीं होगा (स्पष्ट कारणों के लिए)। यह भी स्पष्ट नहीं हो सकता है कि आप ब्रैकेट संकेतन में एक चर का उपयोग कर सकते हैं, अर्थातvar x = 'SomeProperty'; alert(myObj[x])
किप

2
"जावास्क्रिप्ट में सभी वस्तुओं को हैशटेबल्स / साहचर्य सरणियों के रूप में लागू किया जाता है।" - गलत V8 एक ऑब्जेक्ट को एक छिपे हुए वर्ग + घनी पैक वाले क्षेत्रों के रूप में संग्रहीत करना पसंद करता है। यदि आप उनके लिए अजीब चीजें करते हैं (जैसे कि खेतों को हटाने के लिए) तो यह हार मान लेता है और पर्दे के पीछे हैश मैप का उपयोग करता है।
जॉन ड्वोरक

4
@JDDvorak - हे, तुम पहचानते हो जब यह उत्तर मूल रूप से लिखा गया था, हाँ? यह विवरण अधिकांश उद्देश्यों के लिए पर्याप्त था और अभी भी पर्याप्त है। उस ने कहा, मैं समझता हूं कि थकाऊ रूप से पांडित्य है। :)
जेसन बंटिंग

41

पिछले उत्तरों में से कोई भी इस तथ्य को संबोधित नहीं करता है कि जावास्क्रिप्ट के पास शुरू करने के लिए साहचर्य सरणियां नहीं हैं - arrayजैसे कोई प्रकार नहीं है - देखेंtypeof

क्या जावास्क्रिप्ट है, गतिशील गुणों के साथ वस्तु उदाहरण हैं। जब गुण एक सरणी ऑब्जेक्ट उदाहरण के तत्वों के साथ भ्रमित होते हैं तो खराब चीजें ™ होने के लिए बाध्य होती हैं:

मुसीबत

var elements = new Array()

elements.push(document.getElementsByTagName("head")[0])
elements.push(document.getElementsByTagName("title")[0])
elements["prop"] = document.getElementsByTagName("body")[0]

console.log("number of elements: ", elements.length)   // returns 2
delete elements[1]
console.log("number of elements: ", elements.length)   // returns 2 (?!)

for (var i = 0; i < elements.length; i++)
{
   // uh-oh... throws a TypeError when i == 1
   elements[i].onmouseover = function () { window.alert("Over It.")}
   console.log("success at index: ", i)
}

समाधान

एक सार्वभौमिक निष्कासन कार्य करने के लिए जो आपके ऊपर नहीं उड़ता है, उपयोग करें:

Object.prototype.removeItem = function (key) {
   if (!this.hasOwnProperty(key))
      return
   if (isNaN(parseInt(key)) || !(this instanceof Array))
      delete this[key]
   else
      this.splice(key, 1)
};

//
// Code sample.
//
var elements = new Array()

elements.push(document.getElementsByTagName("head")[0])
elements.push(document.getElementsByTagName("title")[0])
elements["prop"] = document.getElementsByTagName("body")[0]

console.log(elements.length)                        // returns 2
elements.removeItem("prop")
elements.removeItem(0)
console.log(elements.hasOwnProperty("prop"))        // returns false as it should
console.log(elements.length)                        // returns 1 as it should

8
इस समाधान में दो मुद्दे हैं: यह इस तथ्य को छुपाता है कि जेएस में सरणियां और वस्तुएं पूरी तरह से अलग जानवर हैं (आप इसे जानते हैं, लेकिन स्पष्ट रूप से ओपी नहीं करता है) और यह प्रोटोटाइप का उपयोग करता है। ओपी बेहतर होगा यदि वह सरणियों और वस्तुओं के बारे में सीखता है (और तदनुसार अपने चर नाम देगा) - दोनों के बीच के अंतर को छिपाने की कोशिश करने से उसे और अधिक परेशानी में पड़ जाएगा। IMHO के।
जॉन्डोडो

1
@johndodo - ArrayJS में सभी वस्तुएं हैं, कोशिश करें typeof new Array();या typeof []सत्यापित करें। Arrayएक वस्तु का एक निश्चित प्रकार है और सभी "अलग जानवर" नहीं है। जेएस में, वस्तुओं को उनके निर्माता के नाम और प्रोटोटाइप श्रृंखला द्वारा प्रतिष्ठित किया जाता है, प्रोटोटाइप-आधारित प्रोग्रामिंग देखें
शाऊल

9
आप द्वारा मुख्य बात अनदेखा की जा रही है। मुझे पता है कि सरणियाँ ऑब्जेक्ट्स भी हैं, लेकिन इसका मतलब यह नहीं है कि उन्हें इस तरह से उपयोग करना बुद्धिमान है। प्रोग्रामर को यह तय करना चाहिए कि क्या वह सरणी (पुश, पॉप, [... ...) के रूप में या ऑब्जेक्ट / "साहचर्य सरणी" के रूप में कुछ का उपयोग करना चाहता है। मिक्स एंड मैच एक अच्छी रेसिपी नहीं है, ठीक इसके कारण उन समस्याओं को हल करने की कोशिश की जा रही है जिन्हें आप छिपाना चाहते हैं। यदि आप पहले से तय कर लेते हैं कि कौन सा डिज़ाइन पैटर्न (सरणी या ऑब्जेक्ट) का उपयोग करना है तो ऐसी कोई समस्या नहीं होगी।
जॉन्डोडो

7
@ जोंडोडो - आप किन समस्याओं के बारे में विशेष रूप से बात कर रहे हैं? उपरोक्त कोड का उद्देश्य एक साधारण बहुरूपी कार्य प्रदान करके कमी deleteऑपरेटर के संबंध में Arrayहै।
शाऊल

1
deleteकमी नहीं है। deleteगुणों को दूर करने के लिए डिज़ाइन किया गया है। बस। हटाए गए ऑपरेटर को किसी सरणी के सूचकांक में लागू करने से उस सूचकांक को हटा दिया जाता है। इसे और क्या चाहिए? आपको एक विरल सरणी के साथ छोड़ दिया जाता है, जो भाषा की एक विशेषता है। यदि आप एक विरल सरणी नहीं चाहते हैं, तो सूचकांक को न हटाएं: उपयोग करें spliceया pop
बेन एस्टन

35

यह केवल ऑब्जेक्ट को हटाता है, लेकिन फिर भी सरणी की लंबाई को समान रखता है।

हटाने के लिए आपको कुछ करने की आवश्यकता है जैसे:

array.splice(index, 1);

11
वास्तव में, लेकिन इस मामले में एक सरणी का उपयोग नहीं किया जा रहा है, बस एक सादा पुरानी वस्तु है, इस प्रकार इसकी कोई लंबाई या ब्याह विधि नहीं है।
मूगू सेप

2
@Andreaa Panagiotidis को छोड़कर जब हम Arrays के बारे में बात नहीं कर रहे हैं, जिस स्थिति में यह 100% गलत है time
Drenai

17

जबकि स्वीकृत उत्तर सही है, यह स्पष्टीकरण याद कर रहा है कि यह क्यों काम करता है।

सबसे पहले, आपके कोड को इस तथ्य को प्रतिबिंबित करना चाहिए कि यह एक सरणी नहीं है :

var myObject = new Object();
myObject["firstname"] = "Bob";
myObject["lastname"] = "Smith";
myObject["age"] = 25;

ध्यान दें कि सभी ऑब्जेक्ट (सहित) Array एस ) का उपयोग इस तरह से किया जा सकता है। हालांकि, वस्तुओं पर काम करने के लिए मानक JS सरणी फ़ंक्शंस (पॉप, पुश, ...) की अपेक्षा न करें!

जैसा कि स्वीकृत उत्तर में कहा गया है, आप तब deleteवस्तुओं से प्रविष्टियों को हटाने के लिए उपयोग कर सकते हैं:

delete myObject["lastname"]

आपको तय करना चाहिए कि आप कौन सा मार्ग लेना चाहते हैं - या तो वस्तुओं (साहचर्य सरणियों / शब्दकोशों) का उपयोग करें या सरणियों (मानचित्रों) का उपयोग करें। इन दोनों को कभी मिक्स न करें।


6
बहुत अच्छा जवाब। मैं केवल इसे पढ़ने वाले किसी व्यक्ति को सलाह दूंगा कि जावास्क्रिप्ट में एरर्स को 'मैप्स' के रूप में सारगर्भित नहीं किया जाना चाहिए, बल्कि 'सूचियों' के रूप में। ऐसा इसलिए है क्योंकि आपको सरणियों का उपयोग करते समय तत्वों के सूचकांक पर नियंत्रण रखने की कोशिश नहीं करनी चाहिए। यदि आप कोशिश करते हैं कि ... ठीक है, बस नहीं: डी
rodolfo42

6

spliceवस्तु सरणी से आइटम को पूरी तरह से हटाने के लिए विधि का उपयोग करें :

Object.prototype.removeItem = function (key, value) {
    if (value == undefined)
        return;

    for (var i in this) {
        if (this[i][key] == value) {
            this.splice(i, 1);
        }
    }
};

var collection = [
    { id: "5f299a5d-7793-47be-a827-bca227dbef95", title: "one" },
    { id: "87353080-8f49-46b9-9281-162a41ddb8df", title: "two" },
    { id: "a1af832c-9028-4690-9793-d623ecc75a95", title: "three" }
];

collection.removeItem("id", "87353080-8f49-46b9-9281-162a41ddb8df");

1
यह एक अधिक सामान्य समाधान है, इसे आपकी js फ़ाइल में जोड़ा जा सकता है और यह विधि सभी सरणियों के लिए उपलब्ध होगी, न कि केवल एक सरणी के लिए।
हुसैन

6

जैसा कि अन्य उत्तरों ने उल्लेख किया है, कि आप जो उपयोग कर रहे हैं वह एक जावास्क्रिप्ट सरणी नहीं है, बल्कि एक जावास्क्रिप्ट वस्तु है, जो अन्य भाषाओं में लगभग एक सहयोगी सरणी की तरह काम करती है, सिवाय इसके कि सभी कुंजियाँ तार में बदल जाती हैं। नया मैप कुंजी को उनके मूल प्रकार के रूप में संग्रहीत करता है।

यदि आपके पास एक सरणी और एक वस्तु नहीं थी, तो आप सरणी के .filter फ़ंक्शन का उपयोग कर सकते हैं , बिना हटाए गए आइटम के बिना एक नया सरणी वापस करने के लिए:

var myArray = ['Bob', 'Smith', 25];
myArray = myArray.filter(function(item) {
    return item !== 'Smith';
});

यदि आपके पास एक पुराना ब्राउज़र और jQuery है, तो jQuery के पास एक $.grepविधि है जो समान रूप से काम करती है:

myArray = $.grep(myArray, function(item) {
    return item !== 'Smith';
});

सही व्याख्या। मैंने वांछित परिणाम प्राप्त करने के लिए फ़िल्टर का उपयोग किया। क्या आप बताएंगे कि ऑब्जेक्ट से सरणी को हटाने के लिए रिटर्न आइटम कैसे काम करता है। मैं मान रहा हूं कि यह सरणी को तब तक लौटाता है जब तक कि इसमें आपके द्वारा शामिल स्ट्रिंग शामिल नहीं है।
एडवर्ड


5

आप ऑब्जेक्ट का उपयोग कर रहे हैं, आपके पास शुरू करने के लिए एक सहयोगी सरणी नहीं है। एक साहचर्य सरणी के साथ, आइटम जोड़ना और निकालना इस प्रकार है:

    Array.prototype.contains = function(obj) 
    {
        var i = this.length;
        while (i--) 
        {
            if (this[i] === obj) 
            {
                return true;
            }
        }
        return false;
    }


    Array.prototype.add = function(key, value) 
    {
        if(this.contains(key))
            this[key] = value;
        else
        {
            this.push(key);
            this[key] = value;
        }
    }


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



    // Read a page's GET URL variables and return them as an associative array.
    function getUrlVars()
    {
        var vars = [], hash;
        var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');

        for(var i = 0; i < hashes.length; i++)
        {
            hash = hashes[i].split('=');
            vars.push(hash[0]);
            vars[hash[0]] = hash[1];
        }

        return vars;
    }



    function ForwardAndHideVariables() {
        var dictParameters = getUrlVars();

        dictParameters.add("mno", "pqr");
        dictParameters.add("mno", "stfu");

        dictParameters.remove("mno");



        for(var i = 0; i < dictParameters.length; i++)
        {
            var key = dictParameters[i];
            var value = dictParameters[key];
            alert(key + "=" + value);
        }
        // And now forward with HTTP-POST
        aa_post_to_url("Default.aspx", dictParameters);
    }


    function aa_post_to_url(path, params, method) {
        method = method || "post";

        var form = document.createElement("form");

        //move the submit function to another variable
        //so that it doesn't get written over if a parameter name is 'submit'
        form._submit_function_ = form.submit;

        form.setAttribute("method", method);
        form.setAttribute("action", path);

        for(var i = 0; i < params.length; i++)
        {
            var key = params[i];

            var hiddenField = document.createElement("input");
            hiddenField.setAttribute("type", "hidden");
            hiddenField.setAttribute("name", key);
            hiddenField.setAttribute("value", params[key]);

            form.appendChild(hiddenField);
        }

        document.body.appendChild(form);
        form._submit_function_(); //call the renamed function
    }

4

आप इसे स्पष्ट रूप से 'अपरिभाषित' बताकर अपने नक्शे से एक प्रविष्टि निकाल सकते हैं। आपके मामले में जैसा:

myArray ["lastname"] = अपरिभाषित;


यह उन मामलों में उपयोगी हो सकता है जहां कोई यह सुनिश्चित नहीं करता है कि कुंजी शब्दकोश में मौजूद है या नहीं, लेकिन यदि ऐसा होता है तो उसे सुरक्षित करना चाहता है। अगर मैं गलत हूँ तो मुझे सुधारो।
हसन बेग

3

यदि किसी कारण से डिलीट कुंजी काम नहीं कर रही है (जैसे यह मेरे लिए काम नहीं कर रही है)

आप इसे अलग कर सकते हैं और फिर अपरिभाषित मानों को फ़िल्टर कर सकते हैं

// to cut out one element via arr.splice(indexToRemove, numberToRemove);
array.splice(key, 1)
array.filter(function(n){return n});

अलग-अलग हटाए गए तत्वों के बाद से न तो कोशिश करें और न ही उन्हें चेन करें;


3

हम इसे फंक्शन के रूप में भी इस्तेमाल कर सकते हैं। यदि कोई प्रोटोटाइप के रूप में उपयोग किया जाता है तो कोणीय कुछ त्रुटि फेंकता है। साभार @HarpyWar इसने मुझे एक समस्या को हल करने में मदद की।

var removeItem = function (object, key, value) {
    if (value == undefined)
        return;

    for (var i in object) {
        if (object[i][key] == value) {
            object.splice(i, 1);
        }
    }
};

var collection = [
    { id: "5f299a5d-7793-47be-a827-bca227dbef95", title: "one" },
    { id: "87353080-8f49-46b9-9281-162a41ddb8df", title: "two" },
    { id: "a1af832c-9028-4690-9793-d623ecc75a95", title: "three" }
];

removeItem(collection, "id", "87353080-8f49-46b9-9281-162a41ddb8df");


1

"delete"कीवर्ड का उपयोग करके , यह जावास्क्रिप्ट में एरे से एलीमेंट एलिमेंट को हटा देगा।

उदाहरण के लिए,

निम्नलिखित कथनों पर विचार करें।

var arrayElementToDelete = new Object();

arrayElementToDelete["id"]           = "XERTYB00G1"; 
arrayElementToDelete["first_name"]   = "Employee_one";
arrayElementToDelete["status"]       = "Active"; 

delete arrayElementToDelete["status"];

कोड की अंतिम पंक्ति उस सरणी तत्व को हटा देगी जो कुंजी सरणी से "स्थिति" है।


0
var myArray = newmyArray = new Object(); 
myArray["firstname"] = "Bob";
myArray["lastname"] = "Smith";
myArray["age"] = 25;

var s = JSON.stringify(myArray);

s.replace(/"lastname[^,}]+,/g,'');
newmyArray = JSON.parse(p);

लूपिंग / iterates के बिना हमें समान परिणाम मिलता है


0

"एरेस" के लिए:

यदि आप सूचकांक जानते हैं:

array.splice(index, 1);

यदि आप मूल्य जानते हैं:

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

deleteवस्तुओं के मामले में अच्छी तरह से काम करने के लिए सबसे उत्कट उत्तर लेकिन वास्तविक सरणियों के लिए नहीं। अगर मैं इसका उपयोग deleteकरता हूं तो यह तत्वों को छोरों से निकालता है लेकिन तत्व को रखता है emptyऔर सरणी की लंबाई नहीं बदलता है। यह कुछ परिदृश्यों में एक समस्या हो सकती है।

उदाहरण के लिए, अगर मैं myArray.toString () myArray पर करता हूं तो deleteइसे हटाने के बाद खाली प्रविष्टि बनाता है, यानी।


0

मेरे लिए एकमात्र काम करने का तरीका:

function removeItem (array, value) {
    var i = 0;
    while (i < array.length) {
        if(array[i] === value) {
            array.splice(i, 1);
        } else {
            ++i;
        }
    }
    return array;
}

उपयोग:

var new = removeItem( ["apple","banana", "orange"],  "apple");
// ---> ["banana", "orange"]

इसके बजाय फ़िल्टर का उपयोग क्यों नहीं करें? यह फिल्टर के लिए एक आदर्श उपयोग मामला है
कोड Maniac
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.