टाइपस्क्रिप्ट मानचित्र पर Iterating


134

मैं एक टाइपस्क्रिप्ट मानचित्र पर पुनरावृत्त करने की कोशिश कर रहा हूं, लेकिन मुझे त्रुटियां मिलती रहती हैं और मुझे इस तरह की तुच्छ समस्या के लिए अभी तक कोई समाधान नहीं मिला है।

मेरा कोड है:

myMap : Map<string, boolean>;
for(let key of myMap.keys()) {
   console.log(key);
}

और मुझे त्रुटि मिलती है:

टाइप करें 'IterableIteratorShim <[string, boolean]>' कोई अरै टाइप या स्ट्रिंग टाइप नहीं है।

पूर्ण स्टैक ट्रेस:

 Error: Typescript found the following errors:
  /home/project/tmp/broccoli_type_script_compiler-input_base_path-q4GtzHgb.tmp/0/src/app/project/project-data.service.ts (21, 20): Type 'IterableIteratorShim<[string, boolean]>' is not an array type or a string type.
    at BroccoliTypeScriptCompiler._doIncrementalBuild (/home/project/node_modules/angular-cli/lib/broccoli/broccoli-typescript.js:115:19)
    at BroccoliTypeScriptCompiler.build (/home/project/node_modules/angular-cli/lib/broccoli/broccoli-typescript.js:43:10)
    at /home/project/node_modules/broccoli-caching-writer/index.js:152:21
    at lib$rsvp$$internal$$tryCatch (/home/project/node_modules/rsvp/dist/rsvp.js:1036:16)
    at lib$rsvp$$internal$$invokeCallback (/home/project/node_modules/rsvp/dist/rsvp.js:1048:17)
    at lib$rsvp$$internal$$publish (/home/project/node_modules/rsvp/dist/rsvp.js:1019:11)
    at lib$rsvp$asap$$flush (/home/project/node_modules/rsvp/dist/rsvp.js:1198:9)
    at _combinedTickCallback (internal/process/next_tick.js:67:7)
    at process._tickCallback (internal/process/next_tick.js:98:9)

मैं कोणीय-क्ली बीटा 5 और टाइपस्क्रिप्ट 1.8.10 का उपयोग कर रहा हूं और मेरा लक्ष्य es5 है। क्या किसी को यह समस्या थी?


4
इसका उत्तर github github.com/Microsoft/TypeScript/issues/…
yurzui

जवाबों:


210

आप Map.prototype.forEach((value, key, map) => void, thisArg?) : voidइसके बजाय उपयोग कर सकते हैं

इसे इस तरह उपयोग करें:

myMap.forEach((value: boolean, key: string) => {
    console.log(key, value);
});

15
बस इसी में भाग गया। जैसे टाइपप्रति के अनुसार, नक्शे यात्रा के लिए कल्पना का सम्मान किया जाता है कम से कम प्रतीत नहीं होता है MDN जो एक पाश के लिए-की निर्दिष्ट करता है। .forEachउप-इष्टतम है, क्योंकि आप इसे तोड़ नहीं सकते हैं, AFAIK
Samjones

14
dunno क्यों इसके मूल्य तो कुंजी। पीछे लगता है।
पॉल रूनी

@PaRRooney ऐसा है जिसके साथ संभवतः सामंजस्य स्थापित करना है Array.prototype.map
अहमद फ़सीह

1
यदि हमें जो चाहिए, वह इस पुनरावृत्ति प्रक्रिया को कैसे रोक सकता है?
जावारनर


36

बस Array.from()इसे बदलने के लिए विधि का उपयोग करें Array:

myMap : Map<string, boolean>;
for(let key of Array.from( myMap.keys()) ) {
   console.log(key);
}

5
नक्शे को बदलना एक बहुत ही प्रदर्शन-भूखा संचालन है और समस्या को हल करने का सही तरीका नहीं है जो अनिवार्य रूप से भाषा के मुख्य भागों को छिपाने वाले संकलक हैं। बस <any>नक्शा -cast के लिए-के साथ यह दोहराना चाहते।
Kilves

1
खबरदार: मैंने सोचा था कि मानचित्र को "किसी भी" में डालने के लिए ऊपर दिए गए @Kilves का सुझाव एक सुंदर समाधान था। जब मैंने इसे किया, तो कोड शिकायत के बिना संकलित और भाग गया, लेकिन वास्तव में मैप को पुनरावृत्त नहीं किया गया था - लूप की सामग्री को कभी भी निष्पादित नहीं किया गया था। Array.from()रणनीति यहाँ प्रस्तावित मेरे लिए काम किया है।
23

मैंने यह भी कोशिश की, यह मेरे लिए भी काम नहीं करता है, जो कि ईएस 6 का हिस्सा है और यहां तक ​​कि अधिकांश ब्राउज़रों के लिए "बस काम" करना चाहिए, यह सोचकर भी बेवकूफी होती है। लेकिन मुझे लगता है कि हमारे कोणीय ओवरलोडर्स ज़ोन में कुछ जादुई मम्बो जंबो का उपयोग करते हैं। यह काम नहीं करने के लिए, क्योंकि वे 6 से नफरत करते हैं। आह।
नोव

28

Array.from , Array.prototype.forEach () , और एरो फ़ंक्शंस का उपयोग करना :

अधिक दोहराएं कुंजी :

Array.from(myMap.keys()).forEach(key => console.log(key));

मूल्यों पर फेरबदल करें :

Array.from(myMap.values()).forEach(value => console.log(value));

प्रविष्टियों पर Iterate :

Array.from(myMap.entries()).forEach(entry => console.log('Key: ' + entry[0] + ' Value: ' + entry[1]));

2
निश्चित नहीं है कि, मेरे पास मानचित्र <स्ट्रिंग, कस्टोमक्लास> जैसे नक्शे क्यों हैं। उपरोक्त विधियों में से कोई भी काम नहीं किया गया है सिवाय Array.from (myMap.values ​​()) के। forEach (मान => कंसोल.लॉग (मान)) ;;
राजश्री जीआर

27

इसने मेरे लिए काम किया। टाइपस्क्रिप्ट संस्करण: 2.8.3

for (const [key, value] of Object.entries(myMap)) { 
    console.log(key, value);
}

7
मुझे यह प्राप्त करने के लिए Object.entries (myMap) को सिर्फ myMap.entries () में बदलकर काम किया। मुझे यह उत्तर पसंद है क्योंकि यह .forEach कॉल्स के नुकसान से बचने में त्रुटि करता है।
encrest

2
टिप्पण लायक है कि आपके अगर targetमें tsconfigहै es5कि यह एक त्रुटि फेंकता है, लेकिन साथ es6काम करता है सही ढंग से। आप केवल for (const [key, value] of myMap)लक्ष्य करते समय भी कर सकते हैंes6
बेंजामिन वोगलर

16

प्रति पर "नया टाइपप्रति 2.3 रिलीज नोट्स --downlevelIteration" :

for..of statements, एरे विनाशकारी, और एरे, कॉल, और नई अभिव्यक्ति में प्रसार तत्वों का उपयोग करते हुए उपलब्ध ES5 / E3 में Symbol.iterator का समर्थन करते हैं --downlevelIteration

यह डिफ़ॉल्ट रूप से सक्षम नहीं है! पूर्ण पुनरावृति समर्थन पाने के लिए , "downlevelIteration": trueअपने को जोड़ें tsconfig.jsonया --downlevelIterationध्वज को पास करें tsc

इसके स्थान पर, आप लिख सकते हैं for (let keyval of myMap) {...}और keyvalस्वचालित रूप से अनुमान लगाया जाएगा।


यह डिफ़ॉल्ट रूप से बंद क्यों है? टाइपस्क्रिप्ट योगदानकर्ता @aluanhaddad के अनुसार ,

यह वैकल्पिक है क्योंकि यह उत्पन्न कोड के आकार पर बहुत महत्वपूर्ण प्रभाव डालता है, और संभावित रूप से प्रदर्शन पर, iterables के सभी उपयोगों (सरणियों सहित) के लिए होता है।

आप ES2015 (लक्षित कर सकते हैं "target": "es2015"में tsconfig.jsonया tsc --target ES2015) या बाद में, सक्रिय करने के downlevelIterationएक चाहती हैं, लेकिन अगर आप ES5 / ES3 लक्षित कर रहे हैं, तो आप बेंचमार्क हो सकता है यह सुनिश्चित करने के इटरेटर समर्थन प्रभाव प्रदर्शन नहीं करता है (अगर यह होता है, आप बेहतर हो सकता है Array.fromरूपांतरण या forEachकुछ अन्य समाधान के साथ बंद )।


कोणीय का उपयोग करते समय इसे सक्षम करने के लिए यह ठीक है या खतरनाक है?
साइमन_वेअर


8

मैं नवीनतम टीएस और नोड (क्रमशः v2.6 और v8.9) का उपयोग कर रहा हूं और मैं कर सकता हूं:

let myMap = new Map<string, boolean>();
myMap.set("a", true);
for (let [k, v] of myMap) {
    console.log(k + "=" + v);
}

क्या आप इस बात की पुष्टि कर सकते हैं कि आपको सबसे पहले "downlevelIteration": trueअपने में सेट होना था tsconfig.json?
अहमद फ़सीह

3
हालांकि downlevelIteraton, मेरा लक्ष्य निर्धारित नहीं है es2017
lazieburd

क्या मैं मैप <string, CustomClass []> एलिमेंट के लिए ऐसा नहीं कर सकता? संकलक का कहना है कि यह प्रकार या स्ट्रिंग प्रकार की एक सरणी नहीं है।
राजश्री जीआर

यह मेरे लिए 2.8 पर काम नहीं करता है - मुझे मिलता हैType 'Map<K, V>' is not an array type or a string type.
सिमोन_वेअर

3

आप Map.entries () के लिए सरणी मानचित्र विधि भी लागू कर सकते हैं:

[...myMap.entries()].map(
     ([key, value]: [string, number]) => console.log(key, value)
);

इसके अलावा, अन्य उत्तरों के अनुसार, आपको अपने tsconfig.json (कंपाइलर के तहत) में स्तरीय पुनरावृत्ति को सक्षम करना पड़ सकता है:

  "downlevelIteration": true,

यह फीचर टाइपस्क्रिप्ट 2.3 में पेश किया गया था। टाइपस्क्रिप्ट 1.8.10 के साथ समस्या उत्पन्न हुई
mwe

यदि आप "downlevelIteration" का उपयोग नहीं कर सकते हैं, तो आप उपयोग कर सकते हैं:const projected = Array.from(myMap).map(...);
Efrain

1

HTML डॉक्यूमेंट में इसका उपयोग करने के लिए बस एक सरल स्पष्टीकरण।

यदि आपके पास एक प्रकार का नक्शा (कुंजी, सरणी) है तो आप इस तरह से सरणी को इनिशियलाइज़ करते हैं:

public cityShop: Map<string, Shop[]> = new Map();

और उस पर पुनरावृति करने के लिए, आप मुख्य मानों से एक सरणी बनाते हैं।

बस इसे एक सरणी के रूप में उपयोग करें:

keys = Array.from(this.cityShop.keys());

फिर, HTML में, आप उपयोग कर सकते हैं:

*ngFor="let key of keys"

इस लूप के अंदर, आपको बस इसके साथ सरणी मान मिलेगा:

this.cityShop.get(key)

किया हुआ!



-1

यदि आपको वास्तव में नेस्टेड फ़ंक्शन पसंद नहीं हैं, तो आप कुंजियों पर भी पुनरावृति कर सकते हैं:

myMap : Map<string, boolean>;
for(let key of myMap) {
   if (myMap.hasOwnProperty(key)) {
       console.log(JSON.stringify({key: key, value: myMap[key]}));
   }
}

ध्यान दें, आपको गैर-कुंजी पुनरावृत्तियों को फ़िल्टर करना होगा hasOwnProperty, यदि आप ऐसा नहीं करते हैं, तो आपको एक चेतावनी या एक त्रुटि मिलती है।


html में नक्शे पर पुनरावृति कैसे करें? यह बिल्कुल काम नहीं करता है। <div ng-repeat = "(key, value) में model.myMap"> {{key}}। </ div>
शिन्या कोइज़ुमी

@ powerfade917 यह काम नहीं करता है, यह केवल सरणियों के लिए काम करता है क्योंकि कोणीय कचरे का ढेर है। लेकिन इसे एक नए प्रश्न के रूप में पूछें और इसलिए आप सीखेंगे, कि कोणीय कचरा का ढेर नहीं है, लेकिन आपको इसे एक सरणी में बदलना होगा। ध्यान दें, आप प्रोग्रामिंग के शीर्ष पर भी नहीं हैं, क्योंकि आप कोणीय और टाइपस्क्रिप्ट के बीच अंतर करने में असमर्थ हैं।
पीटर - मोनिका
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.