किसी अन्य सरणी में निहित सभी तत्वों को निकालें


222

मैं एक जावास्क्रिप्ट सरणी से सभी तत्वों को निकालने के लिए एक कुशल तरीका खोज रहा हूं यदि वे किसी अन्य सरणी में मौजूद हैं।

// If I have this array:
var myArray = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];

// and this one:
var toRemove = ['b', 'c', 'g'];

मैं इस राज्य में इसे छोड़ने के लिए myArray पर काम करना चाहता हूं: ['a', 'd', 'e', 'f']

JQuery के साथ, मैं उपयोग कर रहा हूँ grep()और inArray(), जो अच्छी तरह से काम करता है:

myArray = $.grep(myArray, function(value) {
    return $.inArray(value, toRemove) < 0;
});

वहाँ एक शुद्ध जावास्क्रिप्ट तरीका यह करने के लिए looping और splicing के बिना है?




1
संभव है कि आप जावास्क्रिप्ट या jquery में दूसरे से एक सरणी निकाल सकते हैं - जब आपने प्रश्न लिखा हो तो आपके द्वारा दिए गए सुझावों पर बहुत ध्यान नहीं दिया जा सकता है
mplungjan

कोई बात नहीं, यह हमेशा किसी न किसी स्तर पर शामिल होगा।
ब्लू स्काई

यदि आप वास्तव में इसे "कुशल" बनाना चाहते हैं, तो आप कार्यात्मक प्रकार के तरीकों का उपयोग नहीं करेंगे .filter()। इसके बजाय आप forलूप का उपयोग करेंगे । आप बच सकते हैं .splice()यदि मूल आदेश को बनाए रखने की आवश्यकता नहीं है। या फिर .splice()अधिक कुशल बनाने के तरीके हैं यदि आपको लगता है कि हटाने के लिए कई आइटम होंगे।
ब्लू स्काई

जवाबों:


379

Array.filter()विधि का प्रयोग करें :

myArray = myArray.filter( function( el ) {
  return toRemove.indexOf( el ) < 0;
} );

छोटे सुधार, जैसे ब्राउज़र समर्थन Array.includes()बढ़ा है:

myArray = myArray.filter( function( el ) {
  return !toRemove.includes( el );
} );

तीर कार्यों का उपयोग करके अगला अनुकूलन :

myArray = myArray.filter( ( el ) => !toRemove.includes( el ) );

23
ओपी: यदि आप अंडरस्कोर का उपयोग कर रहे हैं। जेएस वहाँ है .difference()जो मूल रूप से ऐसा करता है।
बिल क्रिशवेल

मुझे इसकी ही खोज थी। धन्यवाद। @BillCriswell, मैं अंडरस्कोर की जांच करूंगा।
टैप करें

1
@AlecRust के सभी तत्वों को कन्वर्ट toRemove()के कॉलबैक में अपर केस और परिवर्तन के elलिए el.toUpperCase()
सिरको

5
या इससे कम:myArray = myArray.filter( el => !toRemove.includes( el ) );
538ROMEO

1
क्या यह आदेश n ^ 2 नहीं है?
फ्रेज़र किर्कमैन

34

filterविधि चाल करना चाहिए:

const myArray = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
const toRemove = ['b', 'c', 'g'];

// ES5 syntax
const filteredArray = myArray.filter(function(x) { 
  return toRemove.indexOf(x) < 0;
});

यदि आपकी toRemoveसरणी बड़ी है, तो इस तरह का लुकअप पैटर्न अक्षम हो सकता है। यह एक मानचित्र बनाने के लिए अधिक उपयुक्त होगा ताकि लुकअप के O(1)बजाय लुकअप हो O(n)

const toRemoveMap = toRemove.reduce(
  function(memo, item) {
    memo[item] = memo[item] || true;
    return memo;
  },
  {} // initialize an empty object
);

const filteredArray = myArray.filter(function (x) {
  return toRemoveMap[x];
});

// or, if you want to use ES6-style arrow syntax:
const toRemoveMap = toRemove.reduce((memo, item) => ({
  ...memo,
  [item]: true
}), {});

const filteredArray = myArray.filter(x => toRemoveMap[x]);

24

यदि आप वस्तुओं की एक सरणी का उपयोग कर रहे हैं। फिर नीचे दिए गए कोड को जादू करना चाहिए, जहां एक वस्तु संपत्ति नकली वस्तुओं को हटाने के लिए मानदंड होगी।

नीचे दिए गए उदाहरण में, डुप्लिकेट को प्रत्येक आइटम के नाम की तुलना करते हुए हटा दिया गया है।

इस उदाहरण का प्रयास करें। http://jsfiddle.net/deepak7641/zLj133rh/

var myArray = [
  {name: 'deepak', place: 'bangalore'}, 
  {name: 'chirag', place: 'bangalore'}, 
  {name: 'alok', place: 'berhampur'}, 
  {name: 'chandan', place: 'mumbai'}
];
var toRemove = [
  {name: 'deepak', place: 'bangalore'},
  {name: 'alok', place: 'berhampur'}
];

for( var i=myArray.length - 1; i>=0; i--){
 	for( var j=0; j<toRemove.length; j++){
 	    if(myArray[i] && (myArray[i].name === toRemove[j].name)){
    		myArray.splice(i, 1);
    	}
    }
}

alert(JSON.stringify(myArray));



11

ECMAScript 6 सेट का उपयोग दो सरणियों के विभिन्न तत्वों की गणना के लिए किया जा सकता है:

const myArray = new Set(['a', 'b', 'c', 'd', 'e', 'f', 'g']);
const toRemove = new Set(['b', 'c', 'g']);

const difference = new Set([...myArray].filter((x) => !toRemove.has(x)));

console.log(Array.from(difference)); // ["a", "d", "e", "f"]


8

मैंने अभी लागू किया है:

Array.prototype.exclude = function(list){
        return this.filter(function(el){return list.indexOf(el)<0;})
}

इस रूप में उपयोग करें:

myArray.exclude(toRemove);

1
prototypesदेशी वस्तुओं का विस्तार करना अच्छा नहीं है Array। भाषा के भविष्य के विकास के साथ दीर्घकालिक संघर्ष हो सकता है ( मामला देखेंflatten )
MarcoL

6

यदि आप नए ES5 सामान का उपयोग नहीं कर सकते हैं तो filterमुझे लगता है कि आप दो छोरों के साथ फंस गए हैं:

for( var i =myArray.length - 1; i>=0; i--){
  for( var j=0; j<toRemove.length; j++){
    if(myArray[i] === toRemove[j]){
      myArray.splice(i, 1);
    }
  }
}

फ़िल्टर "नया HTML5 सामान" नहीं है
goofballLogic

मुझे "ES5 सामान" लिखना चाहिए था। यह
मार्कोल

6
var myArray = [
  {name: 'deepak', place: 'bangalore'}, 
  {name: 'chirag', place: 'bangalore'}, 
  {name: 'alok', place: 'berhampur'}, 
  {name: 'chandan', place: 'mumbai'}
];
var toRemove = [
  {name: 'deepak', place: 'bangalore'},
  {name: 'alok', place: 'berhampur'}
];



myArray = myArray.filter(ar => !toRemove.find(rm => (rm.name === ar.name && ar.place === rm.place) ))

क्या आप इस तरह के एक अच्छी तरह से प्राप्त प्रश्न पर कुछ स्पष्टीकरण जोड़ना चाहेंगे?
harmonica141

1
मैंने समस्या के समाधान के लिए घंटों खोज की और बस इसे पाया, बस भयानक। आपका बहुत बहुत धन्यवाद!
टार्वो मेसेप


3

आप _.differenceBy का उपयोग लॉश से कर सकते हैं

const myArray = [
  {name: 'deepak', place: 'bangalore'}, 
  {name: 'chirag', place: 'bangalore'}, 
  {name: 'alok', place: 'berhampur'}, 
  {name: 'chandan', place: 'mumbai'}
];
const toRemove = [
  {name: 'deepak', place: 'bangalore'},
  {name: 'alok', place: 'berhampur'}
];
const sorted = _.differenceBy(myArray, toRemove, 'name');

यहाँ उदाहरण कोड: CodePen


क्या होगा यदि विशेषता ऑब्जेक्ट के अंदर नेस्टेड है? आपके मामले में कुछ टेस्ट जैसे {नाम: 'डीपैक', जगह: 'बैंगलौर', नेस्टेड: {टेस्ट: 1}}
चरिथ जयसंका

2

कैसे संभव के बारे में सबसे सरल:

var myArray = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
var toRemove = ['b', 'c', 'g'];

var myArray = myArray.filter((item) => !toRemove.includes(item));
console.log(myArray)


2
ध्यान रखें कि includesES7 से पहले उपलब्ध नहीं है।
ग्रेग

0

किसी अन्य सरणी में निहित सभी तत्वों को निकालने का उचित तरीका केवल स्रोत को हटाकर स्रोत सरणी को एक ही वस्तु बनाना है:

Array.prototype.removeContained = function(array) {
  var i, results;
  i = this.length;
  results = [];
  while (i--) {
    if (array.indexOf(this[i]) !== -1) {
      results.push(this.splice(i, 1));
    }
  }
  return results;
};

या कॉफीस्क्रिप्ट समतुल्य:

Array.prototype.removeContained = (array) ->
  i = @length
  @splice i, 1 while i-- when array.indexOf(@[i]) isnt -1

क्रोम देव उपकरणों के अंदर परीक्षण:

19: 33: 04.447 a = 1
19: 33: 06.354 b = 2
19: 33: 07.615 c = 3
19: 33: 09.981 गिरफ़्तार = [a, b, c]
19: 33: 16.460 arr1

19: 33: 20.317 गिरफ्तार 1 === गिरफ्तारी
19: 33: 20.331 सच है

19: 33: 43.592 arr.removeContained ([एक, ग])
19: 33: 52.433 आगमन === arr1
19: 33: 52.438 सच

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


यह उत्तर बुरा है क्योंकि यह सर्वोत्तम प्रथाओं से बचता है। विशेष रूप से, उन वस्तुओं को कभी भी संशोधित न करें जो आपके पास नहीं हैं। इस मामले में, आप ऐरे ऑब्जेक्ट को संशोधित कर रहे हैं, जो कि एक बड़ी संख्या है।
हाइब्रिड वेब देव

0

मैं किसी भी अंतर्निहित विधियों का उपयोग किए बिना तर्क का निर्माण करता हूं, कृपया मुझे कोई अनुकूलन या संशोधन बताएं। मैंने जेएस संपादक में परीक्षण किया कि यह ठीक काम कर रहा है।

var myArray = [
            {name: 'deepak', place: 'bangalore'},
            {name: 'alok', place: 'berhampur'},
            {name: 'chirag', place: 'bangalore'},
            {name: 'chandan', place: 'mumbai'},

        ];
        var toRemove = [

            {name: 'chirag', place: 'bangalore'},
            {name: 'deepak', place: 'bangalore'},
            /*{name: 'chandan', place: 'mumbai'},*/
            /*{name: 'alok', place: 'berhampur'},*/


        ];
        var tempArr = [];
        for( var i=0 ; i < myArray.length; i++){
            for( var j=0; j<toRemove.length; j++){
                var toRemoveObj = toRemove[j];
                if(myArray[i] && (myArray[i].name === toRemove[j].name)) {
                    break;
                }else if(myArray[i] && (myArray[i].name !== toRemove[j].name)){
                        var fnd = isExists(tempArr,myArray[i]);
                        if(!fnd){
                            var idx = getIdex(toRemove,myArray[i])
                            if (idx === -1){
                                tempArr.push(myArray[i]);
                            }

                        }

                    }

                }
        }
        function isExists(source,item){
            var isFound = false;
            for( var i=0 ; i < source.length; i++){
                var obj = source[i];
                if(item && obj && obj.name === item.name){
                    isFound = true;
                    break;
                }
            }
            return isFound;
        }
        function getIdex(toRemove,item){
            var idex = -1;
            for( var i=0 ; i < toRemove.length; i++){
                var rObj =toRemove[i];
                if(rObj && item && rObj.name === item.name){
                    idex=i;
                    break;
                }
            }
            return idex;
        }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.