কীভাবে একটি সরল বস্তুকে একটি ES6 মানচিত্রে রূপান্তর করতে?


126

কোনও কারণে আমি এই সাধারণ জিনিসটি এমডিএন ডক্সে খুঁজে পাচ্ছি না (সম্ভবত আমি কেবল এটি মিস করছি)।

আমি আশা করি এটি কাজ করবে:

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

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

... তবে প্রথম লাইন ছুড়ে ফেলেছে TypeError: (var)[Symbol.iterator] is not a function

আমি কীভাবে একটি সরল বস্তু থেকে মানচিত্র তৈরি করব? আমাকে কি সত্যিই প্রথমে কী-মান জোড়ার অ্যারেতে রূপান্তর করতে হবে?


2
FWIW, তা থেকে আপনার গৃহীত উত্তর সুইচিং মূল্য হতে পারে খনি থেকে Nils ' বা bergi এরObject.entriesসত্যিই এটি সর্বোত্তম পদ্ধতির উপর নির্ভর করে Object.keysএবং বার্গির জেনারেটরের ফাংশন পদ্ধতির হয় Object.keysবা এর চেয়ে কিছুটা বেশি সরাসরি Object.entries
টিজে ক্রাউডার

উত্তর:


193

হ্যাঁ, Mapনির্মাতা কী-মান জোড়ার একটি অ্যারে নেন ।

Object.entriesES2017 (19.1.2.5) এ উপলব্ধ একটি নতুন অবজেক্ট স্ট্যাটিক পদ্ধতি ।

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

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

এটি বর্তমানে ফায়ারফক্স 46+ এবং এজ 14+ এবং Chrome এর আরও নতুন সংস্করণে প্রয়োগ করা হয়েছে

আপনার যদি পুরানো পরিবেশ সমর্থন করতে হয় এবং প্রতিস্থাপন আপনার পক্ষে বিকল্প না হয় তবে পলিফিল ব্যবহার করুন, যেমন জর্জের দ্বারা প্রস্তাবিত একটি:

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]])
জর্জি

4
Object.entriesনোডে 7.x যথাযথ (কোনও পতাকা ছাড়াই) বিটিডব্লু অবতরণ করেছে
লি বেনসন

2
নোড 7-তে কেবল অবজেক্ট.এন্ট্রিই নয়, এটি ES2017 চূড়ান্ত নির্দিষ্টকরণেরও একটি অংশ। সুতরাং, এটি গ্রহণযোগ্য উত্তর হওয়া উচিত, আইএমও
অনিল্রেডশীট

1
@ অ্যানিলরেডশিফ্ট - ঠিক আছে, এটি বা জেনারেটরের কার্যকারিতা উত্তর , যেহেতু ওপি মধ্যস্থতাকারীদের এড়ানো একটি সমাধান চেয়েছিল।
টিজে ক্রাউডার

2
দুর্ভাগ্যক্রমে, এটি হবে না।
নেমানজা মিলোস্লাভিজিক

78

জেনারেটর ফাংশন ব্যবহার করে নীলদের উত্তরObject.entries এবং / অথবা বার্গির উত্তর দেখুন । যদিও Object.entriesপ্রশ্নটি জিজ্ঞাসা করার সময় এখনও তা অনুমানের মধ্যে ছিল না, এটি পঞ্চম পর্যায়ে ছিল , পলিফিল এতটাই নিরাপদ এবং এপ্রিল ২০১ 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% নয় isn't সুতরাং সত্যিই, হয় এক। তবে তারা উভয় নীচের চেয়ে ভাল। :-)


আসল উত্তর:

এটিকে আরম্ভ করার জন্য 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-look (এটি কি এখনও একটি জিনিস?) সংস্করণ রয়েছে:

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

(হ্যাঁ, Map#setমানচিত্র রেফারেন্স উপস্থাপিত করে। অনেকেই হয়তো বলবেন এই একটি হল abusage এর reduce।)

বা আমরা অস্পষ্টতার উপরে সত্যই উপরে যেতে পারি :

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

না, আমি কখনই বাস্তবের জন্য এটি করব না। :-)


1
এর Ohar এর @ এবং @ TJCrowder এর সমাধান ফিউশন: var buildMap2 = o => new Map(Object.keys(o).map(k => [k, o[k]]));
7vujy0f0hy


অবজেক্ট.এন্ট্রিগুলির উত্তরগুলি অগ্রাধিকার দেওয়া উচিত
কির

@ কির - সে বা জেনারেটর , হ্যাঁ। আমার সম্পাদনা দেখুন।
টিজে ক্রাউডার

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
@ পুইউ না, আপনার উচিত হবে না এবং এটি একটি খারাপ অভ্যাস। আপনি যদি বস্তুটির উপর বিশ্বাস না করেন তবে আপনার অবশ্যই তার .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 পৃষ্ঠায় রয়েছে () একটি মানচিত্রে রূপান্তরিত করে একটি শিরোনাম শিরোনামের অধীনে :

কোনও বস্তুকে মানচিত্রে রূপান্তর করা

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 এর @ এবং @ TJCrowder এর সমাধান ফিউশন: var buildMap2 = o => new Map(Object.keys(o).map(k => [k, o[k]]));
7vujy0f0hy

ধন্যবাদ, যেমন আমার প্রয়োজন বস্তুর কীগুলিও বাছাই করা দরকার!
স্কটওয়ার্নভার্ট


0

ES6

বস্তুকে মানচিত্রে রূপান্তর করুন:

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

মানচিত্রকে বস্তুতে রূপান্তর করুন:

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

দ্রষ্টব্য: মানচিত্রটিওজ ফাংশন ধরে নেয় মানচিত্র কীগুলি স্ট্রিং (অন্যথায় ব্যর্থ হবে)


-1

কিছু জিকিউরির সহায়তায়,

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

3
2019-এ আমি অনুভব করি যে সমস্যাগুলি সমাধান করার জন্য আমাদের jquery তে নজর রাখা উচিত নয়।
অবরুদ্ধ

jQuery এখনও প্রচুর প্রকল্পে রয়েছে এবং এটি কোনও খারাপ উত্তর নয়, কেবল অনুকূল নয়।
নৌকা কোডার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.