我想开始使用ES6地图而不是JS对象,但我被阻止了,因为我不知道如何JSON.stringify()一个地图。我的键保证是字符串,我的值总是会被列出。我真的必须写一个包装器方法来序列化吗?


当前回答

下面的解决方案工作,即使你有嵌套的地图

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);
}

其他回答

下面的解决方案工作,即使你有嵌套的地图

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);
}

更好的解决方案

    // 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
        }
    }

希望这比上面的答案不那么尴尬。

非常简单的方法。

  const map = new Map();
  map.set('Key1', "Value1");
  map.set('Key2', "Value2");
  console.log(Object.fromEntries(map));

` 输出:

{"Key1": "Value1","Key2": "Value2"}

鉴于您的示例是一个简单的用例,其中键将是简单类型,我认为这是JSON stringify Map的最简单方法。

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

我认为Map的底层数据结构是键值对数组(数组本身)。就像这样:

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

因为底层的数据结构就是我们在Object中找到的。条目,我们可以在Map上使用Object.fromEntries()的原生JavaScript方法,就像在数组上一样:

Object.fromEntries(myMap);

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

然后剩下的就是对结果使用JSON.stringify()。

JSON。stringify和JSON。解析支持第二个参数。替换器和恢复器分别。使用下面的replacer和reviver,可以添加对原生Map对象的支持,包括深度嵌套的值

function replacer(key, value) {
  if(value instanceof Map) {
    return {
      dataType: 'Map',
      value: Array.from(value.entries()), // or with spread: value: [...value]
    };
  } 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);