कैसे forEach पाश में सरणी से तत्व निकालने के लिए?


98

मैं एक तत्व को forEachलूप में एक सरणी में निकालने की कोशिश कर रहा हूं , लेकिन मैंने जो मानक समाधान देखे हैं, उससे मुझे परेशानी हो रही है।

यह मैं वर्तमान में कोशिश कर रहा हूँ:

review.forEach(function(p){
   if(p === '\u2022 \u2022 \u2022'){
      console.log('YippeeeE!!!!!!!!!!!!!!!!')
      review.splice(p, 1);
   }
});

मुझे पता है कि यह ifइसलिए हो रहा है क्योंकि मैं YippeeeeeE!!!!!!!!!!!!!कंसोल में देख रहा हूं ।

मेरी समस्या: मुझे पता है कि मेरे लिए लूप और यदि तर्क ध्वनि है, लेकिन सरणी से वर्तमान तत्व को हटाने का मेरा प्रयास विफल हो रहा है।

अपडेट करें:

Xotic750 का जवाब देने की कोशिश की, और तत्व अभी भी हटाया नहीं जा रहा है:

यहाँ मेरे कोड में फ़ंक्शन है:

review.forEach(function (item, index, object) {
    if (item === '\u2022 \u2022 \u2022') {
       console.log('YippeeeE!!!!!!!!!!!!!!!!')
       object.splice(index, 1);
    }
    console.log('[' + item + ']');
});

यहां वह आउटपुट है जहां सरणी अभी भी नहीं निकाली गई है:

[Scott McNeil]
[reviewed 4 months ago]
[ Mitsubishi is AMAZING!!!]
YippeeeE!!!!!!!!!!!!!!!!
[•  •]

तो जाहिर है कि अगर यह निर्देश के अनुसार हो रहा है, लेकिन यह भी स्पष्ट है कि [• • •] अभी भी है।


8
क्या कोई कारण है जो आप उपयोग कर रहे हैं forEach? यदि आप आइटम निकालना चाहते हैं, तो सबसे उपयुक्त फ़ंक्शन है filter
जॉन

2
यदि आपको संदर्भ को मूल सरणी में रखने की आवश्यकता नहीं है।
Xotic750

हां, हम संदर्भ को मूल सरणी में रखना चाहते हैं।
नौसिखिएग्रम्र

यह आपके प्रश्न से स्पष्ट नहीं है, कि आपको क्या समस्या है? क्या आप एक उदाहरण दे सकते हैं, शायद एक jsFiddle? ऐसा लगता है कि आपको शायद अपने लिएindexitemsplice
Xotic750

@ Xotic750 क्षमा करें, स्पष्टीकरण जोड़ा गया।
नौसिखिएग्रम्र

जवाबों:


236

ऐसा लगता है कि आप ऐसा करने की कोशिश कर रहे हैं?

Irayate और Array.prototype.splice का उपयोग करके एक सरणी को म्यूट करें

var pre = document.getElementById('out');

function log(result) {
  pre.appendChild(document.createTextNode(result + '\n'));
}

var review = ['a', 'b', 'c', 'b', 'a'];

review.forEach(function(item, index, object) {
  if (item === 'a') {
    object.splice(index, 1);
  }
});

log(review);
<pre id="out"></pre>

जो साधारण मामले के लिए ठीक काम करता है जहां आपके पास आसन्न सरणी आइटम के समान मानों में से 2 नहीं हैं, अन्य बुद्धिमानों के पास यह समस्या है।

var pre = document.getElementById('out');

function log(result) {
  pre.appendChild(document.createTextNode(result + '\n'));
}

var review = ['a', 'a', 'b', 'c', 'b', 'a', 'a'];

review.forEach(function(item, index, object) {
  if (item === 'a') {
    object.splice(index, 1);
  }
});

log(review);
<pre id="out"></pre>

तो हम इस समस्या के बारे में क्या कर सकते हैं जब एक सरणी को पुनरावृत्त करना और बदलना है? वैसे इसका सामान्य उपाय है रिवर्स में काम करना। ES3 का उपयोग करते समय, लेकिन यदि आप चाहें तो चीनी के लिए उपयोग कर सकते हैं

var pre = document.getElementById('out');

function log(result) {
  pre.appendChild(document.createTextNode(result + '\n'));
}

var review = ['a' ,'a', 'b', 'c', 'b', 'a', 'a'],
  index = review.length - 1;

while (index >= 0) {
  if (review[index] === 'a') {
    review.splice(index, 1);
  }

  index -= 1;
}

log(review);
<pre id="out"></pre>

ठीक है, लेकिन आप ES5 पुनरावृत्ति विधियों का उपयोग करना चाहते थे। अच्छी तरह से और विकल्प Array.prototype.filter का उपयोग करना होगा लेकिन यह मूल सरणी को म्यूट नहीं करता है बल्कि एक नया बनाता है, इसलिए जब आप सही उत्तर प्राप्त कर सकते हैं तो यह वह नहीं है जो आप निर्दिष्ट करते हैं।

हम ES5 Array.prototype.reduceRight का भी उपयोग कर सकते हैं , न कि अपनी संपत्ति को कम करने की संपत्ति के लिए बल्कि इसके पुनरावृत्ति गुण, यानी रिवर्स में पुनरावृति के लिए।

var pre = document.getElementById('out');

function log(result) {
  pre.appendChild(document.createTextNode(result + '\n'));
}

var review = ['a', 'a', 'b', 'c', 'b', 'a', 'a'];

review.reduceRight(function(acc, item, index, object) {
  if (item === 'a') {
    object.splice(index, 1);
  }
}, []);

log(review);
<pre id="out"></pre>

या हम जैसे ES5 Array.protoype.indexOf का उपयोग कर सकते हैं ।

var pre = document.getElementById('out');

function log(result) {
  pre.appendChild(document.createTextNode(result + '\n'));
}

var review = ['a', 'a', 'b', 'c', 'b', 'a', 'a'],
  index = review.indexOf('a');

while (index !== -1) {
  review.splice(index, 1);
  index = review.indexOf('a');
}

log(review);
<pre id="out"></pre>

लेकिन आप विशेष रूप से ES5 Array.prototype.forEach का उपयोग करना चाहते हैं , तो हम क्या कर सकते हैं? अच्छी तरह से हमें सरणी की एक उथली प्रतिलिपि बनाने के लिए Array.prototyp.slice का उपयोग करने की आवश्यकता है और Array.prototype.reverse तो हम मूल सरणी को म्यूट करने के लिए रिवर्स में काम कर सकते हैं।

var pre = document.getElementById('out');

function log(result) {
  pre.appendChild(document.createTextNode(result + '\n'));
}

var review = ['a', 'a', 'b', 'c', 'b', 'a', 'a'];

review.slice().reverse().forEach(function(item, index, object) {
  if (item === 'a') {
    review.splice(object.length - 1 - index, 1);
  }
});

log(review);
<pre id="out"></pre>

अंत में ES6 हमें कुछ और विकल्प प्रदान करता है, जहाँ हमें उथली प्रतियां बनाने और उन्हें उलटने की आवश्यकता नहीं होती है। विशेष रूप से हम जेनरेटर और इटरेटर का उपयोग कर सकते हैं । हालांकि वर्तमान में समर्थन काफी कम है।

var pre = document.getElementById('out');

function log(result) {
  pre.appendChild(document.createTextNode(result + '\n'));
}

function* reverseKeys(arr) {
  var key = arr.length - 1;

  while (key >= 0) {
    yield key;
    key -= 1;
  }
}

var review = ['a', 'a', 'b', 'c', 'b', 'a', 'a'];

for (var index of reverseKeys(review)) {
  if (review[index] === 'a') {
    review.splice(index, 1);
  }
}

log(review);
<pre id="out"></pre>

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

तो वहाँ हम यह है, समाधान के साथ एक और अधिक पूर्ण जवाब है कि अभी भी किनारे मामलों है। बहुत पहले कोड का उदाहरण अभी भी सही है लेकिन जैसा कि कहा गया है, यह मुद्दों के बिना नहीं है।


जवाब के लिए धन्यवाद। मैंने आपके समाधान का उपयोग करने की कोशिश की, लेकिन यह अभी भी तत्व को सरणी से नहीं निकाल रहा है। मैं प्रश्न में विवरण डालूँगा।
नौसिखिएग्रम्र

मेरे उदाहरण में, के console.log(review);बाद रखो forEach
Xotic750

4
सावधान, यह तब टूटता है जब दो लगातार तत्वों को हटाने के लिए: var review = ['a', 'a', 'c', 'b', 'a ’]; उपज देगा '' a ',' c ',' b ']
quentinadam

4
नोट - यह उत्तर गलत है! अनुक्रमणिका द्वारा सरणी के माध्यम से फ़ार्च पुनरावृति। एक बार जब आप निम्नलिखित आइटम परिवर्तन के सूचकांक को पुनरावृत्त करते हुए तत्वों को हटाते हैं। इस उदाहरण में, एक बार जब आप पहले 'a' को हटा देते हैं, तो इंडेक्स नंबर 1 अब 'c' बन जाता है। इसलिए पहले 'बी' का मूल्यांकन भी नहीं किया जाता है। चूँकि आपने इसे हटाने की कोशिश नहीं की थी, यह ठीक हुआ, लेकिन ऐसा नहीं है। आपको सरणी की रिवर्स कॉपी के माध्यम से पुनरावृति करनी चाहिए, और फिर मूल सरणी में आइटम हटाएं।
दानबर्स

4
@ Xotic750 - मूल उत्तर (अब पहला कोड स्निपेट होने के नाते) गलत है, क्योंकि फॉरएच सरणी में सभी तत्वों के माध्यम से लूप नहीं करेगा, जैसा कि मैंने पिछली टिप्पणी में समझाया था। मुझे पता है कि सवाल यह था कि फॉरएच लूप में तत्वों को कैसे हटाया जाए, लेकिन इसका सरल उत्तर यह है कि आप ऐसा नहीं करते हैं। चूंकि बहुत से लोग उन उत्तरों को पढ़ रहे हैं, और कई बार नेत्रहीन नकल के जवाब (विशेष रूप से स्वीकृत उत्तर), कोड में खामियों को नोट करना महत्वपूर्ण है। मुझे लगता है कि पाश जबकि रिवर्स सबसे सरल, सबसे कुशल और सबसे पठनीय समाधान है और स्वीकृत उत्तर होना चाहिए
danbars

37

Array.prototype.filterइसके बजाय का उपयोग करें forEach:

var pre = document.getElementById('out');

function log(result) {
  pre.appendChild(document.createTextNode(result + '\n'));
}

var review = ['a', 'b', 'c', 'b', 'a', 'e'];
review = review.filter(item => item !== 'a');
log(review);

11

यद्यपि Xotic750 का उत्तर कई अच्छे बिंदु और संभव समाधान प्रदान करता है, कभी-कभी सरल बेहतर होता है

आप जानते हैं कि जिस सरणी पर पुनरावृत्ति हो रही है, उसे पुनरावृति में ही उत्परिवर्तित किया जा रहा है (अर्थात किसी आइटम को हटाते हुए => अनुक्रमणिका परिवर्तन), इस प्रकार सबसे सरल तर्क पुराने जमाने में पीछे की ओर जाना है for (आ ला सी भाषा):

let arr = ['a', 'a', 'b', 'c', 'b', 'a', 'a'];

for (let i = arr.length - 1; i >= 0; i--) {
  if (arr[i] === 'a') {
    arr.splice(i, 1);
  }
}

document.body.append(arr.join());

यदि आप वास्तव में इसके बारे में सोचते हैं, तो ए forEachfor तो यह लूप के लिए एक सिंटैक्टिक शुगर है ... इसलिए यदि यह आपकी मदद नहीं कर रहा है, तो कृपया इसके खिलाफ अपना सिर तोड़ना बंद करें।


1

आप ऐसा करने के बजाय indexOf का उपयोग भी कर सकते हैं

var i = review.indexOf('\u2022 \u2022 \u2022');
if (i !== -1) review.splice(i,1);

1

मैं समझ गया कि आप किसी शर्त का उपयोग करके सरणी से निकालना चाहते हैं और एक और सरणी है जिसमें सरणी से हटाए गए आइटम हैं। सही है?

इस बारे में कैसा है?

var review = ['a', 'b', 'c', 'ab', 'bc'];
var filtered = [];
for(var i=0; i < review.length;) {
  if(review[i].charAt(0) == 'a') {
    filtered.push(review.splice(i,1)[0]);
  }else{
    i++;
  }
}

console.log("review", review);
console.log("filtered", filtered);

उममीद है कि इससे मदद मिलेगी...

वैसे, मैंने 'फॉर-लूप' की तुलना 'फॉरएच' से की है।

यदि किसी स्ट्रिंग में 'f' सम्‍मिलित है, तो परिणाम अलग है।

var review = ["of", "concat", "copyWithin", "entries", "every", "fill", "filter", "find", "findIndex", "flatMap", "flatten", "forEach", "includes", "indexOf", "join", "keys", "lastIndexOf", "map", "pop", "push", "reduce", "reduceRight", "reverse", "shift", "slice", "some", "sort", "splice", "toLocaleString", "toSource", "toString", "unshift", "values"];
var filtered = [];
for(var i=0; i < review.length;) {
  if( review[i].includes('f')) {
    filtered.push(review.splice(i,1)[0]);
  }else {
    i++;
  }
}
console.log("review", review);
console.log("filtered", filtered);
/**
 * review [  "concat",  "copyWithin",  "entries",  "every",  "includes",  "join",  "keys",  "map",  "pop",  "push",  "reduce",  "reduceRight",  "reverse",  "slice",  "some",  "sort",  "splice",  "toLocaleString",  "toSource",  "toString",  "values"] 
 */

console.log("========================================================");
review = ["of", "concat", "copyWithin", "entries", "every", "fill", "filter", "find", "findIndex", "flatMap", "flatten", "forEach", "includes", "indexOf", "join", "keys", "lastIndexOf", "map", "pop", "push", "reduce", "reduceRight", "reverse", "shift", "slice", "some", "sort", "splice", "toLocaleString", "toSource", "toString", "unshift", "values"];
filtered = [];

review.forEach(function(item,i, object) {
  if( item.includes('f')) {
    filtered.push(object.splice(i,1)[0]);
  }
});

console.log("-----------------------------------------");
console.log("review", review);
console.log("filtered", filtered);

/**
 * review [  "concat",  "copyWithin",  "entries",  "every",  "filter",  "findIndex",  "flatten",  "includes",  "join",  "keys",  "map",  "pop",  "push",  "reduce",  "reduceRight",  "reverse",  "slice",  "some",  "sort",  "splice",  "toLocaleString",  "toSource",  "toString",  "values"]
 */

और प्रत्येक पुनरावृत्ति को हटा दें, एक परिणाम भी अलग है।

var review = ["of", "concat", "copyWithin", "entries", "every", "fill", "filter", "find", "findIndex", "flatMap", "flatten", "forEach", "includes", "indexOf", "join", "keys", "lastIndexOf", "map", "pop", "push", "reduce", "reduceRight", "reverse", "shift", "slice", "some", "sort", "splice", "toLocaleString", "toSource", "toString", "unshift", "values"];
var filtered = [];
for(var i=0; i < review.length;) {
  filtered.push(review.splice(i,1)[0]);
}
console.log("review", review);
console.log("filtered", filtered);
console.log("========================================================");
review = ["of", "concat", "copyWithin", "entries", "every", "fill", "filter", "find", "findIndex", "flatMap", "flatten", "forEach", "includes", "indexOf", "join", "keys", "lastIndexOf", "map", "pop", "push", "reduce", "reduceRight", "reverse", "shift", "slice", "some", "sort", "splice", "toLocaleString", "toSource", "toString", "unshift", "values"];
filtered = [];

review.forEach(function(item,i, object) {
  filtered.push(object.splice(i,1)[0]);
});

console.log("-----------------------------------------");
console.log("review", review);
console.log("filtered", filtered);


0

निम्नलिखित आपको सभी तत्व देगा जो आपके विशेष वर्णों के बराबर नहीं है!

review = jQuery.grep( review, function ( value ) {
    return ( value !== '\u2022 \u2022 \u2022' );
} );

0

यहां बताया गया है कि आपको यह कैसे करना चाहिए:

review.forEach(function(p,index,object){
   if(review[index] === '\u2022 \u2022 \u2022'){
      console.log('YippeeeE!!!!!!!!!!!!!!!!')
      review.splice(index, 1);
   }
});

1
मुझे नहीं लगता कि यह मामला है। मैंने अपना कोड बदल दिया मान लिया कि पी एक इंडेक्स था, और अब यह ifबयान में भी नहीं आ रहा है ।
नौसिखिएग्रम्र

3
@WhoCares आपको युक्ति को देखना चाहिए ecma-international.org/ecma-262/5.1/#sec-15.4.4.1.18 कॉलबैक फ़ंक्शन के तर्क हैंitem, index, object
Xotic750
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.