एक सादे वस्तु को ES6 मैप में कैसे बदलें?


128

किसी कारण से मुझे एमडीएन डॉक्स में यह साधारण बात नहीं मिल रही है (शायद मैं इसे याद कर रहा हूं)।

मुझे उम्मीद है कि यह काम करेगा:

const map = new Map({foo: 'bar'});

map.get('foo'); // 'bar'

... लेकिन पहली पंक्ति फेंकी TypeError: (var)[Symbol.iterator] is not a function

मैं एक सादे वस्तु से एक नक्शा कैसे बनाऊं? क्या मुझे वास्तव में इसे कुंजी-मूल्य जोड़े के सरणियों के एक सरणी में बदलना है?


2
Fwiw, यह से अपने स्वीकार किए जाते हैं जवाब स्विचिंग लायक हो सकता है मेरा के लिए निल्स ' या bergi कीObject.entriesवास्तव में बेहतर दृष्टिकोण है Object.keys, और बर्गी का जनरेटर फ़ंक्शन दृष्टिकोण Object.keysया तो की तुलना में थोड़ा अधिक प्रत्यक्ष है Object.entries
टीजे क्राउडर

जवाबों:


195

हां, Mapकंस्ट्रक्टर कुंजी-मूल्य जोड़े की एक सरणी लेता है।

Object.entriesES2017 (19.1.2.5) में उपलब्ध एक नई वस्तु स्थैतिक विधि है ।

const map = new Map(Object.entries({foo: 'bar'}));

map.get('foo'); // 'bar'

यह वर्तमान में फ़ायरफ़ॉक्स 46+ और एज 14+ और क्रोम के नए संस्करणों में लागू किया गया है

यदि आपको पुराने वातावरण का समर्थन करने की आवश्यकता है और वाष्पोत्सर्जन आपके लिए एक विकल्प नहीं है, तो पॉलीफ़िल का उपयोग करें, जैसे कि भूगोल के लिए अनुशंसित एक:

Object.entries = typeof Object.entries === 'function' ? Object.entries : obj => Object.keys(obj).map(k => [k, obj[k]]);

3
एक "पॉलीफ़िल" बल्कि तुच्छ होगा:Object.entries = obj => Object.keys(obj).map(k => [k, obj[k]])
georg

4
Object.entriesNode 7.x उचित (एक ध्वज के बिना) btw में उतरा
ली बेन्सन

2
न केवल Node7 में Object.entries है, यह ES2017 के अंतिम विनिर्देश का भी हिस्सा है। इस प्रकार, यह स्वीकृत उत्तर होना चाहिए, IMO
अनिलरेडशिफ्ट

1
@AnilRedshift - ठीक है, यह या जनरेटर फ़ंक्शन जवाब है , क्योंकि ओपी ने बिचौलियों से बचने के लिए एक समाधान पूछा है।
टीजे क्राउडर

2
दुर्भाग्य से, यह नहीं होगा।
नेमंजा मिलोसावजेविक

78

जनरेटर फ़ंक्शन का उपयोग करके कृपया निल्स का उत्तरObject.entries और / या बर्गी का उत्तर देखेंहालांकि Object.entriesसवाल पूछे जाने के बाद भी यह कल्पना में नहीं था, यह स्टेज 4 पर था , इसलिए पॉलीफ़िल के लिए सुरक्षित था और अप्रैल 2016 (अभी) में वापस भी उपयोग किया गया था। ( यहां के चरणों में अधिक ।) और जनरेटर फ़ंक्शन ES2015 में थे। ओपी ने विशेष रूप से मध्यस्थों से बचने के लिए कहा, और जबकि जनरेटर पूरी तरह से नहीं बचता है, यह नीचे या (थोड़ा) की तुलना में बेहतर काम करता है Object.enties

FWIW, का उपयोग कर Object.entries:

  • [name, value]पास करने के लिए सरणियों की एक सरणी बनाता हैnew Map
  • Mapनिर्माता सरणी पुनरावर्तक पाने के लिए पर एक समारोह कॉल; ऐरे बनाता है और ऐरे इंटरएटर ऑब्जेक्ट बनाता है।
  • Mapनिर्माता का उपयोग करता है कि इटरेटर वस्तु प्रविष्टियों (पाने के लिए [name, value]सरणियों) और नक्शा बनाने

जनरेटर का उपयोग करना:

  • जनरेटर फ़ंक्शन को कॉल करने के परिणामस्वरूप एक जनरेटर ऑब्जेक्ट बनाता है
  • Mapनिर्माता से पुनरावर्तक प्राप्त करने के लिए है कि जनरेटर वस्तु पर एक समारोह कॉल; जनरेटर वस्तु रिटर्न ही है
  • Mapनिर्माता (पुनरावर्तक के रूप में) जनरेटर वस्तु प्रविष्टियों (प्राप्त करने के लिए उपयोग करता [name, value]सरणियों) और नक्शा बनाने

तो: एक कम मध्यस्थ (से सरणी) Object.entries )।

हालाँकि, उपयोग Object.entriesकरना सरल है और उस सरणी को बनाना 99.999% समय का मुद्दा नहीं है। तो वास्तव में, या तो एक। लेकिन वे दोनों नीचे से बेहतर हैं। :-)


मूल उत्तर:

एक को इनिशियलाइज़ करने के लिए Map, आप किसी भी इटेरेटर का उपयोग कर सकते हैं, जो की / अरै के अरेंजमेंट जैसे अरैज़ के रूप में की / वैल्यू पेयर देता है:

const map = new Map([
    ['foo', 'bar']
]);

ऑब्जेक्ट से मैप में कोई अंतर्निहित रूपांतरण नहीं है, लेकिन यह आसानी से किया जाता है Object.keys:

const map = new Map();
let obj = {foo: 'bar'};
Object.keys(obj).forEach(key => {
    map.set(key, obj[key]);
});

आप निश्चित रूप से, अपने आप को एक कार्यकर्ता कार्य दे सकते हैं कि

function buildMap(obj) {
    let map = new Map();
    Object.keys(obj).forEach(key => {
        map.set(key, obj[key]);
    });
    return map;
}

फिर

const map = buildMap({foo: 'bar'});

या यहाँ एक और अधिक l33t- लग रहा है (यह अभी भी एक बात है?) संस्करण:

function buildMap(obj) {
    return Object.keys(obj).reduce((map, key) => map.set(key, obj[key]), new Map());
}

(हां, Map#setनक्शा संदर्भ देता है। कुछ का तर्क है कि यह एक अपमानजनक हैreduce ।)

या हम वास्तव में अस्पष्टता के ऊपर जा सकते हैं:

const buildMap = o => Object.keys(o).reduce((m, k) => m.set(k, o[k]), new Map());

नहीं, मैं असली के लिए ऐसा कभी नहीं करूंगा। :-)


1
@ Ohar's और @ TJCrowder के समाधान का संलयन var buildMap2 = o => new Map(Object.keys(o).map(k => [k, o[k]]));:।
7vujy0f0hy

17
देखें new Map(Object.entries(object)) stackoverflow.com/a/36644558/798133
राफेल जेवियर

Object.entries जवाब पसंद किया जाना चाहिए
Kir

@ कीर - वह या जनरेटर , हाँ। मेरा संपादन देखें।
टीजे क्राउडर

31

क्या मुझे वास्तव में कुंजी-मूल्य जोड़े के सरणियों के एक सरणी में बदलना है?

नहीं, कुंजी-मूल्य जोड़ी सरणियों का एक पुनरावृत्त पर्याप्त है। मध्यवर्ती सरणी बनाने से बचने के लिए आप निम्नलिखित का उपयोग कर सकते हैं:

function* entries(obj) {
    for (let key in obj)
        yield [key, obj[key]];
}

const map = new Map(entries({foo: 'bar'}));
map.get('foo'); // 'bar'

अच्छा उदाहरण - सिर्फ दूसरों के लिए एक नोट, आप if(!obj.hasOwnProperties(key)) continue;लूप की स्थिति के बाद एक अधिकार प्राप्त करना चाहते हैं ताकि आप यह सुनिश्चित कर सकें कि आपको ऑब्जेक्ट प्रोटोटाइप से विरासत में प्राप्त संपत्ति नहीं मिलती है (जब तक कि आप ऑब्जेक्ट पर भरोसा नहीं करते हैं, लेकिन ऑब्जेक्ट्स का उपयोग करते समय इसे वैसे भी करना चाहिए inएक अच्छी आदत के रूप में)।
पुईउ

2
@Puiu नहीं, आपको नहीं करना चाहिए, और यह एक बुरी आदत है। यदि आपको वस्तु पर भरोसा नहीं है, तो आपको उसकी .hasOwnPropertyसंपत्ति पर भी भरोसा नहीं करना चाहिए , और आपको उपयोग करना होगाObject.prototype.hasOwnProperty.call(obj, key)
बर्गी

2
हां, मुझे लगता है कि परेशान न करना सबसे अच्छा अभ्यास है। आपको उन सभी वस्तुओं पर भरोसा करना चाहिए, जो किसी भी तरह की विरासत में मिली संपत्तियों के लिए एन्यूमरेट करने लायक हैं (यानी की-वैल्यू-मैप्स)। (और हां बेशक एन्यूमरेटिंग एरे से बचें )। यदि आपके पास किसी और चीज़ को एनुमरेट करने का एक दुर्लभ मामला है, और आप परेशान हैं, तो आपको कम से कम इसे ठीक से करना चाहिए call। सभी सम्मेलनों से obj.hasOwnProperties(key)पता चलता है कि वे क्या कर रहे हैं पता नहीं है।
बर्गी

3
एक Objectमें बदलना एक Mapमहंगा ऑपरेशन है और ओपी ने विशेष रूप से मध्यवर्ती के बिना एक समाधान के लिए कहा है। तो यह अपवादित उत्तर क्यों नहीं है? खैर, यह पूछना शायद व्यर्थ है, यह सिर्फ मुझे गुस्सा दिलाता है।

1
@tmvnty आपको टाइप करने की आवश्यकता होगी function* entries<T>(obj: T): Generator<readonly [keyof T, T[keyof T]]> {…}yield [key, obj[key]] as const;टाइपस्क्रिप्ट को यह एहसास कराने में भी मदद मिलेगी कि यह ट्यूल की पैदावार है, न कि सरणियाँ।
बेर्गी

11

निल्स द्वारा दिए गए उत्तर में वस्तुओं को नक्शे में बदलने का तरीका बताया गया है, जो मुझे बहुत उपयोगी लगा। हालांकि, ओपी यह भी सोच रहा था कि यह जानकारी एमडीएन डॉक्स में कहां है। हालांकि यह नहीं हो सकता है जब मूल रूप से सवाल पूछा गया था, यह अब MDN पृष्ठ पर Object.entries () के तहत एक मानचित्र पर एक वस्तु को परिवर्तित करने वाले शीर्षक के तहत है जो बताता है:

किसी ऑब्जेक्ट को मैप में बदलना

new Map()निर्माता का एक iterable स्वीकार करता है entries। इसके साथ Object.entries, आप आसानी से Objectइसे इसमें बदल सकते हैं Map:

const obj = { foo: 'bar', baz: 42 }; 
const map = new Map(Object.entries(obj));
console.log(map); // Map { foo: "bar", baz: 42 }

7
const myMap = new Map(
    Object
        .keys(myObj)
        .map(
            key => [key, myObj[key]]
        )
)

1
@ Ohar's और @ TJCrowder के समाधान का संलयन var buildMap2 = o => new Map(Object.keys(o).map(k => [k, o[k]]));:।
7vujy0f0hy

धन्यवाद, जैसा कि मुझे ऑब्जेक्ट कुंजियों को भी सॉर्ट करने की आवश्यकता थी!
16


1

ES6

ऑब्जेक्ट को मैप में बदलें:

const objToMap = (o) => new Map(Object.entries(o));

नक्शे को ऑब्जेक्ट में बदलें:

const mapToObj = (m) => [...m].reduce( (o,v)=>{ o[v[0]] = v[1]; return o; },{} )

नोट: mapToObj फ़ंक्शन मान लेता है कि मानचित्र कुंजियाँ स्ट्रिंग हैं (अन्यथा विफल होंगी)


-1

कुछ JQuery की मदद से,

const myMap = new Map();
$.each( obj, function( key, value ) {
myMap[key] = value;
});

4
2019 में मुझे लगता है कि समस्याओं को हल करने के लिए हमें जौकरी की ओर नहीं देखना चाहिए।
इलक्रक्स

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