আপনি কীভাবে একটি ES6 মানচিত্র JSON.stringify করবেন?


112

আমি জেএস বস্তুর পরিবর্তে ইএস Map মানচিত্রটি ব্যবহার শুরু করতে চাই তবে আমাকে পিছনে আটকে রাখা হচ্ছে কারণ আমি কীভাবে JSON.stringify () কোনও মানচিত্র করব তা বুঝতে পারি না। আমার কীগুলি স্ট্রিং হওয়ার গ্যারান্টিযুক্ত এবং আমার মানগুলি সর্বদা তালিকাবদ্ধ থাকবে। সিরিয়ালাইজ করার জন্য আমাকে কি আসলে একটি র‌্যাপার পদ্ধতি লিখতে হবে?



আমি এটি কাজ করতে সক্ষম হয়েছি। ফলাফল এম্বেড.পিএলএনকিআর.কম / ওএনএলকিউকিউবিডিডিজিউআইআইকিউএলজিইউইউপিভিপি- তে প্লঙ্কার-এ রয়েছে । সমাধানটিতে একটি JSON.stringify (Obj, replacerFunction) ব্যবহার করা হয় যা কোনও মানচিত্র অবজেক্টটি পাস হচ্ছে কিনা তা পরীক্ষা করে দেখায় এবং মানচিত্র অবজেক্টটিকে জাভাস্ক্রিপ্ট অবজেক্টে রূপান্তরিত করে (যে JSON.stringify) তারপরে একটি স্ট্রিংয়ে রূপান্তরিত হবে।
প্যাটস

4
যদি আপনার কীগুলি স্ট্রিং (বা সংখ্যা) এবং আপনার মান অ্যারে হিসাবে গ্যারান্টিযুক্ত থাকে তবে আপনি এর মতো কিছু করতে পারেন [...someMap.entries()].join(';'); আরও জটিল [...someMap.entries()].reduce((acc, cur) => acc + `${cur[0]}:${/* do something to stringify cur[1] */ }`, '')
কোনও কিছুর

@ ওরিওল কী যদি মূল নামটির জন্য ডিফল্ট বৈশিষ্ট্যের সমান হতে পারে? obj[key]আপনি অপ্রত্যাশিত কিছু পেতে পারে। কেস বিবেচনা করুন if (!obj[key]) obj[key] = newList; else obj[key].mergeWith(newList);
ফ্রাঙ্কলিন ইউ

উত্তর:


71

উভয় JSON.stringifyএবং JSON.parseএকটি দ্বিতীয় যুক্তি সমর্থন। replacerএবং reviverযথাক্রমে Replacer এবং নীচে পুনরুদ্ধারকের সাথে গভীর নেস্ট করা মান সহ দেশীয় মানচিত্র অবজেক্টের জন্য সমর্থন যুক্ত করা সম্ভব

function replacer(key, value) {
  const originalObject = this[key];
  if(originalObject instanceof Map) {
    return {
      dataType: 'Map',
      value: Array.from(originalObject.entries()), // or with spread: value: [...originalObject]
    };
  } else {
    return value;
  }
}
function reviver(key, value) {
  if(typeof value === 'object' && value !== null) {
    if (value.dataType === 'Map') {
      return new Map(value.value);
    }
  }
  return value;
}

ব্যবহার :

const originalValue = new Map([['a', 1]]);
const str = JSON.stringify(originalValue, replacer);
const newValue = JSON.parse(str, reviver);
console.log(originalValue, newValue);

অ্যারে, অবজেক্টস এবং মানচিত্রের সংমিশ্রণে গভীর নেস্টিং

const originalValue = [
  new Map([['a', {
    b: {
      c: new Map([['d', 'text']])
    }
  }]])
];
const str = JSON.stringify(originalValue, replacer);
const newValue = JSON.parse(str, reviver);
console.log(originalValue, newValue);

8
এটি এখন অবধি সেরা প্রতিক্রিয়া
ম্যানুয়েল ভেরা সিলভেস্ট্রে

4
অবশ্যই এখানে সেরা উত্তর।
জাভাআরনার

এটিকে সঠিক হিসাবে চিহ্নিত করা হয়েছে। যদিও আমি এটি পছন্দ করি না আপনি একটি মানহীন মানযুক্ত তারের জুড়ে ডেটা "নষ্ট" dataTypeকরতে হবে, আমি পরিষ্কার উপায় সম্পর্কে ভাবতে পারি না। ধন্যবাদ
rynop

@ আরএনপ হ্যাঁ এটি খালি নেটিভ ফাংশনালিটি ব্যবহার না করে নিজের ডেটা স্টোরেজ ফর্ম্যাট সহ একটি ছোট প্রোগ্রামের মতো
পাওয়েল

77

উদাহরণটিতে Mapকোনও বৈশিষ্ট্য না থাকায় আপনি সরাসরি সংশ্লেষ করতে পারবেন না তবে আপনি এটি টিপলসের একটি অ্যারে রূপান্তর করতে পারেন:

jsonText = JSON.stringify(Array.from(map.entries()));

বিপরীতে, ব্যবহার করুন

map = new Map(JSON.parse(jsonText));

6
এটি কোনও JSON অবজেক্টে রূপান্তরিত হয় না, পরিবর্তে অ্যারে অ্যারে রূপান্তর করে। একই জিনিস না। আরও সম্পূর্ণ উত্তরের জন্য নীচে ইভান ক্যারোলের উত্তর দেখুন।
শনি থিরু

4
@ স্যাথিরু টিপলসগুলির একটি অ্যারে Mapগুলি রীতিগত উপস্থাপনা , এটি কনস্ট্রাক্টর এবং পুনরুক্তিকারীর সাথে ভালভাবে চলে। এছাড়াও এটি মানচিত্রের একমাত্র বুদ্ধিমান উপস্থাপনা যা নন-স্ট্রিং কী রয়েছে এবং অবজেক্টটি সেখানে কাজ করবে না।
বার্গি

বার্গি, দয়া করে নোট করুন যে ওপি বলেছিল "আমার কীগুলি স্ট্রিং হওয়ার নিশ্চয়তা"।
শনি থিরু

4
@ সাত্থিরু সেক্ষেত্রে, ব্যবহার করুন JSON.stringify(Object.fromEntries(map.entries()))এবংnew Map(Object.entries(JSON.parse(jsonText)))
বার্গি

@ বার্গি স্ট্রিংফাই যদি keyকোনও বস্তু হিসাবে কাজ করে না যেমন "{"[object Object]":{"b":2}}"- বস্তু কীগুলি মানচিত্রের অন্যতম প্রধান বৈশিষ্ট্য
ড্রেনাই

66

আপনি পারবেন না।

মানচিত্রের কীগুলি বস্তুগুলি সহ যে কোনও কিছু হতে পারে। তবে জেএসএন সিনট্যাক্স কেবল স্ট্রিংকে কী হিসাবে অনুমতি দেয়। সুতরাং এটি সাধারণ ক্ষেত্রে অসম্ভব।

আমার কীগুলি স্ট্রিং হওয়ার গ্যারান্টিযুক্ত এবং আমার মানগুলি সর্বদা তালিকাগুলিতে থাকবে

এই ক্ষেত্রে, আপনি একটি সরল বস্তু ব্যবহার করতে পারেন। এর এই সুবিধাগুলি থাকবে:

  • এটি JSON এ স্ট্রিংফাই করতে সক্ষম হবে।
  • এটি পুরানো ব্রাউজারগুলিতে কাজ করবে।
  • এটি দ্রুত হতে পারে।

33
কৌতূহলী-ইন সর্বশেষ ক্রোমের জন্য, কোনও মানচিত্র '{}'
-তে

আমি "আপনি পারবেন না" বলার সময় আমি কী বুঝাতে চাইছিলাম তা এখানে ব্যাখ্যা করেছি।
ওরিওল

8
"এটি দ্রুত হতে পারে" - আপনার কি কোনও উত্স আছে? আমি কল্পনা করছি একটি সাধারণ হ্যাশ-মানচিত্র অবশ্যই একটি পূর্ণ বর্ধিত বস্তুর চেয়ে দ্রুত হওয়া উচিত, তবে আমার কাছে কোনও প্রমাণ নেই। :)
লিলিমান

4
@ এক্সপ্লোরার যে পরীক্ষাটি ব্যয়বহুল ব্যবহার করে hasOwnProperty। তা না করে ফায়ারফক্স মানচিত্রের চেয়ে অনেক দ্রুত বস্তু পুনরুক্ত করে। যদিও ক্রমের উপরে মানচিত্রগুলি এখনও দ্রুত। jsperf.com/es6-map-vs-object-properties/95
ওরিওল

4
সত্য, মনে হচ্ছে ফায়ারফক্স 45v ক্রোম + 49 ভি এর চেয়ে বেশি দূরে অবজেক্টগুলিকে পুনরাবৃত্তি করে। তবে মানচিত্রগুলি ক্রোমে এখনও বনাম বস্তুগুলিতে জয়লাভ করে।
এক্সপ্লাউডার

16

যদিও বাস্তবে স্ক্রিপ্ট দ্বারা কোনও পদ্ধতি সরবরাহ করা হয়নি, JSON.stingifyআপনি যদি Mapজাভাস্ক্রিপ্টের আদিম মানচিত্রটি মানচিত্র করেন তবে এটি ব্যবহার করে এখনও করা যেতে পারে । আমরা যে নমুনাটি Mapব্যবহার করব তা এখানে ।

const map = new Map();
map.set('foo', 'bar');
map.set('baz', 'quz');

একটি জাভাস্ক্রিপ্ট অবজেক্টে যাচ্ছি

আপনি নিম্নলিখিত সহায়ক ফাংশন দিয়ে জাভাস্ক্রিপ্ট অবজেক্ট আক্ষরিক রূপান্তর করতে পারেন।

const mapToObj = m => {
  return Array.from(m).reduce((obj, [key, value]) => {
    obj[key] = value;
    return obj;
  }, {});
};

JSON.stringify(mapToObj(map)); // '{"foo":"bar","baz":"quz"}'

জাভাস্ক্রিপ্ট অ্যারে অবজেক্টে যাচ্ছি

এর জন্য সহায়ক ফাংশনটি আরও কমপ্যাক্ট হবে

const mapToAoO = m => {
  return Array.from(m).map( ([k,v]) => {return {[k]:v}} );
};

JSON.stringify(mapToAoO(map)); // '[{"foo":"bar"},{"baz":"quz"}]'

অ্যারে অফ অ্যারে যাচ্ছেন

এটি আরও সহজ, আপনি কেবল ব্যবহার করতে পারেন

JSON.stringify( Array.from(map) ); // '[["foo","bar"],["baz","quz"]]'

14

স্প্রেড সিট্যাক্স মানচিত্র ব্যবহার করে এক লাইনে ক্রমিক করা যেতে পারে:

JSON.stringify([...new Map()]);

এবং এটি দিয়ে deserialize:

let map = new Map(JSON.parse(map));

এটি এক-মাত্রিক মানচিত্রের জন্য কাজ করবে তবে কোনও n-মাত্রিক মানচিত্রের জন্য নয়।
ম্যাটসভেন

7

একটি Mapউদাহরণ স্ট্রাইফাই করুন (কী হিসাবে বস্তুগুলি ঠিক আছে) :

JSON.stringify([...map])

বা

JSON.stringify(Array.from(map))

বা

JSON.stringify(Array.from(map.entries()))

আউটপুট ফরমেট:

// [["key1","value1"],["key2","value2"]]

4

একটি ভাল সমাধান

    // somewhere...
    class Klass extends Map {

        toJSON() {
            var object = { };
            for (let [key, value] of this) object[key] = value;
            return object;
        }

    }

    // somewhere else...
    import { Klass as Map } from '@core/utilities/ds/map';  // <--wherever "somewhere" is

    var map = new Map();
    map.set('a', 1);
    map.set('b', { datum: true });
    map.set('c', [ 1,2,3 ]);
    map.set( 'd', new Map([ ['e', true] ]) );

    var json = JSON.stringify(map, null, '\t');
    console.log('>', json);

আউটপুট

    > {
        "a": 1,
        "b": {
            "datum": true
        },
        "c": [
            1,
            2,
            3
        ],
        "d": {
            "e": true
        }
    }

আশা করি যে উপরের উত্তরগুলির চেয়ে কম ক্রিংজি।


আমি নিশ্চিত নই যে এটির মূল নকশা ক্লাসটি একটি
জাসনকে

4
তাদের হতে হবে না, তবে এটি করার আরও নিখুঁত উপায়। বিশেষত, এটি SOLID এর LSP এবং OCP নীতিগুলির সাথে একত্রিত হয়। এটি হল, নেটিভ মানচিত্রটি প্রসারিত হচ্ছে, পরিবর্তিত হচ্ছে না এবং কোনও এখনও একটি স্থানীয় মানচিত্রের সাহায্যে লিসকভ সাবস্টিটিউশন (এলএসপি) ব্যবহার করতে পারে। মঞ্জুর, এটি প্রচুর নভিসি বা কট্টর ফাংশনাল প্রোগ্রামিং লোকেরা পছন্দ করে না তার চেয়ে বেশি ওওপি, তবে কমপক্ষে এটি মৌলিক সফ্টওয়্যার ডিজাইনের নীতিগুলির একটি চেষ্টা করা এবং সত্য ভিত্তিকরেখার উপর নির্ভরশীল। যদি আপনি সলিডের ইন্টারফেস বিভাজন নীতি (আইএসপি) প্রয়োগ করতে চান তবে আপনার একটি ছোট IJSONAbleইন্টারফেস থাকতে পারে (অবশ্যই টাইপস্ক্রিপ্ট ব্যবহার করে)।
কোডি

3

আপনি মানচিত্রে নেস্ট করে থাকলেও নীচে সমাধানটি কাজ করে

function stringifyMap(myMap) {
    function selfIterator(map) {
        return Array.from(map).reduce((acc, [key, value]) => {
            if (value instanceof Map) {
                acc[key] = selfIterator(value);
            } else {
                acc[key] = value;
            }

            return acc;
        }, {})
    }

    const res = selfIterator(myMap)
    return JSON.stringify(res);
}

আপনার উত্তরটি পরীক্ষা না করেই আমি ইতিমধ্যে প্রশংসিত হয়েছি যে এটি কীভাবে নেস্টেড মানচিত্রের সমস্যার দিকে মনোযোগ এনেছে। আপনি এটিকে JSON এ সফলভাবে রূপান্তর করলেও, ভবিষ্যতে যে কোনও পার্সিংয়ের স্পষ্টভাবে সচেতনতা থাকতে হবে যে JSON মূলত একটি Mapএবং (আরও খারাপ) যে প্রতিটি উপ-মানচিত্র (এতে রয়েছে) মূলত একটি মানচিত্রও ছিল। অন্যথায়, এটি নিশ্চিত করার উপায় নেই যে কোনও array of pairsমানচিত্রের পরিবর্তে ঠিক এটির মতো নয় an বস্তু এবং অ্যারেগুলির শ্রেণিবিন্যাস পার্স করার সময় এই বোঝা বহন করে না। কোনও যথাযথ সিরিয়ালাইজেশন Mapসুস্পষ্টভাবে নির্দেশ করে যে এটি একটি Map
লনি সেরা

আরো যে সম্পর্কে এখানে
লনি সেরা

3

আপনার উদাহরণটি একটি সাধারণ ব্যবহারের ক্ষেত্রে দেওয়া হয়েছে যা কীগুলি সাধারণ ধরণের হতে চলেছে, আমি মনে করি এটি কোনও মানচিত্রকে জেএসএন রূপান্তরিত করার সহজতম উপায়।

JSON.stringify(Object.fromEntries(map));

মানচিত্রের অন্তর্নিহিত ডেটা কাঠামো সম্পর্কে আমি যেভাবে চিন্তা করি তা হ'ল কী-মান জোড়ার অ্যারে হিসাবে (নিজেরাই অ্যারে হিসাবে)। সুতরাং, এর মতো কিছু:

const myMap = new Map([
     ["key1", "value1"],
     ["key2", "value2"],
     ["key3", "value3"]
]);

যেহেতু অন্তর্নিহিত ডেটা স্ট্রাকচারটি আমরা অবজেক্ট.এন্ট্রিগুলিতে যা পাই তা হ'ল আমরা Object.fromEntries()কোনও মানচিত্রের নেটিভ জাভাস্ক্রিপ্ট পদ্ধতিটি যেমন কোনও অ্যারেতে ব্যবহার করতে পারি:

Object.fromEntries(myMap);

/*
{
     key1: "value1",
     key2: "value2",
     key3: "value3"
}
*/

এবং তারপরে আপনি যা যা রেখে গেছেন তা হ'ল JSON.stringify () এর ফলাফলটিতে।

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