【问题标题】:Create json string from js Map and String从 js Map 和 String 创建 json 字符串
【发布时间】:2017-11-28 03:42:45
【问题描述】:

我的 REST 控制器需要以下格式的请求输入,它成功地将其转换为包含 Map 和 String 作为参数的 Java 对象:

{ 
"myMap" : { 
    "key1": "value1", 
    "key2": "value2", 
    "key3": "value3"},
"myString": "string value"
}

我从 html 表单中获取数据,如下所示:

var myMap = new Map();
var String = document.getElementById('String').value;
for (var i = 0 ; i<anArray.length ; i++){
    var input = document.getElementsByClassName('input_' + (i+1));
    for (var j = 0 ; j<3 ; j++){
        if (input[j].checked){
            myMap.set(input[j].name, input[j].id);
        }
    }
}

基本上,这段代码归结为:

var myMap = new Map();
myMap.set("key1", "value1");
myMap.set("key2", "value2");
myMap.set("key3", "value3");

这会产生一个包含 {key1 => value1, key2 => value2, etc} 和一个字符串的映射。我一直在尝试将它变成这样的 json 字符串,但它似乎不起作用:

var myJson = {};
myJson.myMap = myMap;
myJson.myString = myString;
var json = JSON.stringify(myJson);

但是,我最终得到以下字符串: `{"myMap":{},"String":"myString"}' 。所以我可能不得不做一些不同的事情来对地图进行字符串化,但我尝试的任何方法都不起作用。

谁能帮帮我?

【问题讨论】:

标签: javascript json


【解决方案1】:

使用 ES6 语法,特别是如果您有嵌套映射(否则Idan Dagan's answer 更简单),您可以使用 JSON.stringify()second 参数,reducer,如下:

JSON.stringify(myMap, (key, value) => (value instanceof Map ? [...value] : value));

【讨论】:

    【解决方案2】:

    这个 hack 可以完成这项工作(但它是全局覆盖,必须小心使用):

      Map.prototype.toString = function() {
    
        let result = {};
    
        this.forEach((key, value) => { result[key] = value;});
    
        return JSON.stringify(result);
      };
    

    【讨论】:

      【解决方案3】:

      您可以使用Array.prototype.reduce 和扩展符号将您的地图简洁地转换为您需要的格式。

      var myMap = new Map();
      myMap.set("key1", "value1");
      myMap.set("key2", "value2");
      myMap.set("key3", "value3");
      var myString = "string value";
      
      function mapToObj (map) {
        return [...map].reduce((acc, val) => {
          acc[val[0]] = val[1];
          return acc;
        }, {});
      }
      
      const json = JSON.stringify({
        myMap: mapToObj(myMap),
        myString: myString
      });
      
      console.log(json);

      【讨论】:

        【解决方案4】:

        您可以编写一个简短的转换函数,将地图变成可以字符串化的对象。

        console.clear()
        
        function mapToObj(map){
          const obj = {}
          for (let [k,v] of map)
            obj[k] = v
          return obj
        }
        
        const myMap = new Map();
        myMap.set("key1", "value1");
        myMap.set("key2", "value2");
        myMap.set("key3", "value3");
        
        const myString = "string value"
        
        const myJson = {};
        myJson.myMap = mapToObj(myMap);
        myJson.myString = myString;
        const json = JSON.stringify(myJson);
        
        console.log(json)

        这是一个可能适用于存在 Map 但其他一些 ES6 构造不适用的版本(不过,这似乎是编辑器设置问题)。

        console.clear()
        
        function mapToObj(map){
          var obj = {}
          map.forEach(function(v, k){
            obj[k] = v
          })
          return obj
        }
        
        var myMap = new Map();
        myMap.set("key1", "value1");
        myMap.set("key2", "value2");
        myMap.set("key3", "value3");
        
        var myString = "string value"
        
        var myJson = {};
        myJson.myMap = mapToObj(myMap);
        myJson.myString = myString;
        var json = JSON.stringify(myJson);
        
        console.log(json)

        【讨论】:

        • myMap 未在功能块内定义,并且未使用函数的 map 参数。我认为您的意思是使用 of map 并且代码只是运行,因为在函数外部定义了 myMap 的定义。
        • 我一直在尝试这个。但是,IntelliJ 一直给我一个错误,说“当前的 javascript 版本不支持”。有什么办法解决吗?
        • @I.Brok 你有支持 Map 但不支持的版本吗?有趣的。我会转换它。
        • @I.Brok in IntelliJ 从下拉菜单中转到设置 -> 语言 -> javascript -> Ecmascript 6。
        • @ Bert Evans 和 @Juan 感谢您的帮助!将版本更改为 Ecmascript 6 就成功了。但仍然感谢您将其转换为 Bert。学习多种方法总是好的。
        【解决方案5】:

        JSON 字符串化具有对象、数组和函数的特殊行为。

        例如:

        JSON.stringify( function(){} ); // output: undefind
        JSON.stringify( [2,undefined,function(){}, 5] ); //output: "[2,null,null,5]"
        

        解决这个问题的一种方法是定义一个 toJSON() 方法返回对象的 JSON 安全版本。

        var myJson = {};
        myJson.toJson = function() {
            return {  /* what ever you need*/}
        }
        

        第二个,也更简单,使用 ES6 语法:

        JSON.stringify([...myMap]);
        

        【讨论】:

          【解决方案6】:

          您可以按如下方式初始化 myMap,而不是 Map

          myMap = {};
          

          将其中的元素设置为 -

          if (input[j].checked){
                  myMap[input[j].name] = input[j].id;
          }
          

          最后,在转换时,您可以执行以下操作 -

          myJSON = {};
          myJSON.myMap = JSON.stringify(myMap);
          myJSON.myString = "StringValue";
          var json = JSON.stringify(myJSON);
          

          【讨论】:

          • 非常感谢。这也很好用。我之前尝试过,但错误地使用了 myMap.[input[j].name] 。现在我只需要考虑哪种方式最适合我,以及我是否真的需要它成为一个地图,或者让它成为一个对象是否可以。如果有的话,我现在更好地理解 Map 和 Object 之间的区别,这总是一件好事。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-03-07
          • 2018-02-14
          • 2011-02-01
          相关资源
          最近更新 更多