ऑब्जेक्ट गुण द्वारा सरणी से ऑब्जेक्ट निकालें


137
var listToDelete = ['abc', 'efg'];

var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me
                      {id:'efg',name:'em'}, // delete me
                      {id:'hij',name:'ge'}] // all that should remain

मैं ऑब्जेक्ट गुण मिलान करके किसी ऑब्जेक्ट को सरणी से कैसे निकालूं?

केवल देशी जावास्क्रिप्ट कृपया।

मुझे बंटवारे का उपयोग करने में परेशानी हो रही है क्योंकि लंबाई प्रत्येक विलोपन के साथ कम हो जाती है। ओरिजिनल इंडेक्स पर क्लोन और स्पिलिंग का उपयोग करना अभी भी आपको कम लंबाई की समस्या से छुटकारा दिलाता है।


1
लूपिंग पीछे की ओर लंबाई की समस्या में परिवर्तन को ठीक करना चाहिए
इयान

1
यह एक ऐसी शर्म की बात है कि किसी वस्तु सरणी से आइटम निकालने का कोई मानक उचित तरीका नहीं है। कोई आश्चर्य नहीं कि इतने सारे 3 पार्टी स्क्रिप्ट हैं। यह एक बुनियादी बात है।
गिटारवादक

जवाबों:


155

मुझे लगता है आप spliceइस तरह से कुछ इस्तेमाल किया ?

for (var i = 0; i < arrayOfObjects.length; i++) {
    var obj = arrayOfObjects[i];

    if (listToDelete.indexOf(obj.id) !== -1) {
        arrayOfObjects.splice(i, 1);
    }
}

बग को ठीक करने के iलिए आपको अगली बार के आसपास की कमी है , तो (और पीछे की तरफ लूप करना भी एक विकल्प है):

for (var i = 0; i < arrayOfObjects.length; i++) {
    var obj = arrayOfObjects[i];

    if (listToDelete.indexOf(obj.id) !== -1) {
        arrayOfObjects.splice(i, 1);
        i--;
    }
}

रैखिक-समय के विलोपन से बचने के लिए, आप उन सरणी तत्वों को लिख सकते हैं जिन्हें आप सरणी पर रखना चाहते हैं :

var end = 0;

for (var i = 0; i < arrayOfObjects.length; i++) {
    var obj = arrayOfObjects[i];

    if (listToDelete.indexOf(obj.id) === -1) {
        arrayOfObjects[end++] = obj;
    }
}

arrayOfObjects.length = end;

और आधुनिक समय में रेखीय समय के लुकअप से बचने के लिए, आप हैश सेट का उपयोग कर सकते हैं:

const setToDelete = new Set(listToDelete);
let end = 0;

for (let i = 0; i < arrayOfObjects.length; i++) {
    const obj = arrayOfObjects[i];

    if (setToDelete.has(obj.id)) {
        arrayOfObjects[end++] = obj;
    }
}

arrayOfObjects.length = end;

जिसे एक अच्छे कार्य में लपेटा जा सकता है:

const filterInPlace = (array, predicate) => {
    let end = 0;

    for (let i = 0; i < array.length; i++) {
        const obj = array[i];

        if (predicate(obj)) {
            array[end++] = obj;
        }
    }

    array.length = end;
};

const toDelete = new Set(['abc', 'efg']);

const arrayOfObjects = [{id: 'abc', name: 'oh'},
                        {id: 'efg', name: 'em'},
                        {id: 'hij', name: 'ge'}];

filterInPlace(arrayOfObjects, obj => !toDelete.has(obj.id));
console.log(arrayOfObjects);

यदि आपको इसे करने की आवश्यकता नहीं है, तो यह है Array#filter:

const toDelete = new Set(['abc', 'efg']);
const newArray = arrayOfObjects.filter(obj => !toDelete.has(obj.id));

79

आप इस तरह से किसी भी 3 पार्टी के काम का उपयोग किए बिना इसके गुणों में से एक को हटा सकते हैं:

var removeIndex = array.map(item => item.id)
                       .indexOf("abc");

~removeIndex && array.splice(removeIndex, 1);

1
यह एक बहुत ही सुंदर जवाब है।
स्कॉट सिल्वी

एक और बात मैं चाहता हूं, सरणी में हर वस्तु के लिए अलग बटन होंगे। अगर मैं उस विशेष बटन को हटाए गए सरणी बटन में हटाना चाहता हूं और उसे किसी अन्य माध्यमिक सरणी में ले जाना चाहिए। इसे कैसे करना है । मैंने आइटम बनाने के लिए कोणीय js एनजी-दोहराने का उपयोग किया है। क्या आप मेरी मदद कर सकते हैं
थिलक राज

बहुत अच्छा और सुरुचिपूर्ण दृष्टिकोण। प्रशंसा! सावधानी के लिए बस एक चीज; यदि आवश्यक इंडेक्स मैप सरणी पर नहीं मिला है, तो यह -1 वापस आ जाएगा; इस प्रकार ब्याह अंतिम तत्व को हटा देगा।
मर्सी

15
या यदि आप अंतिम पंक्ति पर टिल्ड द्वारा भ्रमित हो जाते हैं, तो आपको यह अधिक स्पष्ट लग सकता है: (removeIndex> = 0) && array.splice (removeIndex, 1);
वोजजस

1
@ संवेदनशीलता - क्या आपके उदाहरण में टिल्ड पर कोई दस्तावेज है? मैंने ऐसा पहले कभी नहीं देखा।
webdad3

43

लॉश / अंडरस्कोर के साथ:

यदि आप मौजूदा सरणी को स्वयं संशोधित करना चाहते हैं, तो हमें ब्याह का उपयोग करना होगा । यहाँ थोड़ा बेहतर का उपयोग कर पठनीय तरीका है / findWhere अंडरस्कोर / lodash की:

var items= [{id:'abc',name:'oh'}, // delete me
                  {id:'efg',name:'em'},
                  {id:'hij',name:'ge'}];

items.splice(_.indexOf(items, _.findWhere(items, { id : "abc"})), 1);

ES5 या उच्चतर के साथ

( बिना लॉश / अंडरस्कोर के )

ES5 के बाद हमारे पास findIndexएरे पर विधि है, इसलिए बिना लॉश / अंडरस्कोर के यह आसान है

items.splice(items.findIndex(function(i){
    return i.id === "abc";
}), 1);

(ES5 लगभग सभी morden ब्राउज़रों में समर्थित है)

FindIndex , और इसके ब्राउज़र संगतता के बारे में


मैं ऑब्जेक्ट की सरणी में सभी आइटम कैसे निकालूं लेकिन मुझे कॉलबैक की भी आवश्यकता है
मुहामिन

कॉलबैक से आपका क्या तात्पर्य है, आप सरणी से ऑब्जेक्ट को हटाने के लिए उपरोक्त कोड का उपयोग कर सकते हैं ..
राहुल आर।

1
अच्छा है। मैं इसे अपने
टूलबेल

एक और बात मैं चाहता हूं, सरणी में हर वस्तु के लिए अलग बटन होंगे। अगर मैं उस विशेष बटन को हटाए गए सरणी बटन में हटाना चाहता हूं और उसे किसी अन्य माध्यमिक सरणी में ले जाना चाहिए। इसे कैसे करना है । मैंने आइटम बनाने के लिए कोणीय js एनजी-दोहराने का उपयोग किया है। क्या आप मेरी मदद कर सकते हैं
थिलक राज

1
इस ES5 सुझाव से प्यार करें, क्योंकि इसे छोटे रूप में भी लिखा जा सकता हैitems.splice(items.findIndex(i => i.id === "abc"), 1)
ब्राम्ही

27

findIndex आधुनिक ब्राउज़रों के लिए काम करता है:

var myArr = [{id:'a'},{id:'myid'},{id:'c'}];
var index = arr.findIndex(function(o){
     return o.id === 'myid';
})
if (index !== -1) myArr.splice(index, 1);

मुझे यह आधुनिक उत्तर पसंद है, सिवाय आपके कोड के मामले को नहीं पकड़ता है जब सूचकांक = -1
rmcsharry

2
दूसरों की तुलना में बहुत सरल उत्तर और ठीक काम करता है।
अरुण

सरल अभी तक शक्तिशाली asnwer
शैली

15

किसी ऑब्जेक्ट द्वारा दिए गए सरणी में आईडी को हटाना;

const hero = [{'id' : 1, 'name' : 'hero1'}, {'id': 2, 'name' : 'hero2'}];
//remove hero1
const updatedHero = hero.filter(item => item.id !== 1);

10

यदि आप इसे मौजूदा सरणी से हटाना चाहते हैं और नया नहीं बनाना चाहते हैं, तो प्रयास करें:

var items = [{Id: 1},{Id: 2},{Id: 3}];
items.splice(_.indexOf(items, _.find(items, function (item) { return item.Id === 2; })), 1);

7
ध्यान दें कि इस उत्तर के लिए अंडरस्कोर लाइब्रेरी की आवश्यकता है
जोशुआ डेविड

2
मैं इसकी अनुशंसा नहीं करूंगा क्योंकि यदि तत्व नहीं मिला है तो _.indexOf -1 => आइटम वापस कर देगा। कृपया (-1,1)
user1441287

6

iसमस्या से बचने के लिए अपघटन द्वारा रिवर्स में लूप :

for (var i = arrayOfObjects.length - 1; i >= 0; i--) {
    var obj = arrayOfObjects[i];

    if (listToDelete.indexOf(obj.id) !== -1) {
        arrayOfObjects.splice(i, 1);
    }
}

या उपयोग करें filter:

var newArray = arrayOfObjects.filter(function(obj) {
    return listToDelete.indexOf(obj.id) === -1;
});

5

सेट और ES6 फ़िल्टर का उपयोग करके इसे देखें।

  let result = arrayOfObjects.filter( el => (-1 == listToDelete.indexOf(el.id)) );
  console.log(result);

यहाँ JsField: https://jsfiddle.net/jsq0a0p1/1 है


1
अच्छी तरह से काम!
एंटनी केपिन्स्की

मेरे विचार में सबसे आधुनिक और सुरुचिपूर्ण दृष्टिकोण।
एसी पैट्रिस

4

केवल देशी जावास्क्रिप्ट कृपया।

एक विकल्प के रूप में, अधिक "कार्यात्मक" समाधान, ECMAScript 5 पर काम करना, आप उपयोग कर सकते हैं:

var listToDelete = ['abc', 'efg'];
var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me
                      {id:'efg',name:'em'}, // delete me
                      {id:'hij',name:'ge'}]; // all that should remain

arrayOfObjects.reduceRight(function(acc, obj, idx) {
    if (listToDelete.indexOf(obj.id) > -1)
        arrayOfObjects.splice(idx,1);
}, 0); // initial value set to avoid issues with the first item and
       // when the array is empty.

console.log(arrayOfObjects);
[ { id: 'hij', name: 'ge' } ]

ECMA-262 में 'Array.prototype.reduceRight' की परिभाषा के अनुसार :

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

तो यह एक वैध उपयोग है reduceRight


2
var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me
                      {id:'efg',name:'em'}, // delete me
                      {id:'hij',name:'ge'}] // all that should remain

जैसा आपका जवाब वैसा ही होगा। जब आप किसी विशेष वस्तु पर क्लिक करते हैं तो मुझे डिलीट फंक्शन के लिए परम में इंडेक्स भेजते हैं। यह सरल कोड आकर्षण की तरह काम करेगा।

function deleteme(i){
    if (i > -1) {
      arrayOfObjects.splice(i, 1);
    }
}


1

फ़िल्टर और indexOf के साथ

withLodash = _.filter(arrayOfObjects, (obj) => (listToDelete.indexOf(obj.id) === -1));
withoutLodash = arrayOfObjects.filter(obj => listToDelete.indexOf(obj.id) === -1);

फ़िल्टर और शामिल हैं

withLodash = _.filter(arrayOfObjects, (obj) => (!listToDelete.includes(obj.id)))
withoutLodash = arrayOfObjects.filter(obj => !listToDelete.includes(obj.id));

0

यदि आपको लघु और स्व वर्णनात्मक पैरामीटर पसंद हैं या आप उपयोग नहीं करना चाहते हैं spliceऔर सीधे फ़ॉरवर्ड फ़िल्टर के साथ या यदि आप मेरे जैसे एक SQL व्यक्ति हैं:

function removeFromArrayOfHash(p_array_of_hash, p_key, p_value_to_remove){
    return p_array_of_hash.filter((l_cur_row) => {return l_cur_row[p_key] != p_value_to_remove});
}

और एक नमूना उपयोग:

l_test_arr = 
[
    {
         post_id: 1,
        post_content: "Hey I am the first hash with id 1"
    },
    {
        post_id: 2,
        post_content: "This is item 2"
    },
    {
        post_id: 1,
        post_content: "And I am the second hash with id 1"
    },
    {
        post_id: 3,
        post_content: "This is item 3"
    },
 ];



 l_test_arr = removeFromArrayOfHash(l_test_arr, "post_id", 2); // gives both of the post_id 1 hashes and the post_id 3
 l_test_arr = removeFromArrayOfHash(l_test_arr, "post_id", 1); // gives only post_id 3 (since 1 was removed in previous line)

-1

आप उपयोग कर सकते हैं filter। यदि स्थिति सही है, तो यह विधि हमेशा तत्व देता है। इसलिए यदि आप आईडी से हटाना चाहते हैं तो आपको दिए गए आईडी से मेल नहीं खाने वाले सभी तत्व को रखना होगा। यहाँ एक उदाहरण है:

arrayOfObjects = arrayOfObjects.filter (obj => obj.id! = idToRemove)

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