【问题标题】:JavaScript Convert nested Map to objectJavaScript 将嵌套 Map 转换为对象
【发布时间】:2019-12-27 21:21:57
【问题描述】:

我想将一个 es6 嵌套的 Map 转换为一个对象。

我试过这段代码:

    mapToObjectRec(m) {
      let lo = {}
      for(let[k,v] of m) {
          if(v instanceof Map) {
              lo[k] = this.mapToObjectRec(v)
          }
          else {
              lo[k] = v
          }
      }
      return lo
    }

我想做这个功能的反面:

export declare type IElementsMap = Map<string, IElements>;


deserializeElements(json: any): IElementsMaps | any {
    const elementsMap = new Map<string, IElementsMap>();

    if (Array.isArray(json)) {
      json.forEach(outer => {
        const elementMap = new Map<string, IElements>();
        outer[1].forEach(inner => {
          elementMap.set(inner[0], inner[1]);
        });
        elementsMap.set(outer[0], elementMap);
      });

      return elementsMap;
    }

    return json;
  }

我想在负载请求(发布请求)中发送转换后的数据。

【问题讨论】:

  • 因为 Map 实例可以使用任何类型的键,所以将 Map 转换为普通对象并不总是可能的,至少在没有一些构造字符串属性名称(或我猜的符号)的机制的情况下并非如此。
  • 另外你也没有提到你现有的代码到底出了什么问题。
  • 这是在 JavaScript 还是 TypeScript 中?
  • 别再迷惑自己了:json.forEach(...) 让你认为 json 是一个数组,但 JSON 始终是一个字符串。如果您的变量是一个元素数组,请将其命名为 elems 或其他名称。
  • 您应该提供输入和预期输出的示例。问题的答案取决于您的输入类型。

标签: javascript dictionary ecmascript-6


【解决方案1】:

如果 Map 的键是数字、字符串或符号,则以下技术将起作用 -

const m =
  new Map
    ( [ [ 'a', 1 ]
      , [ 'b', 2 ]
      , [ 'c'
        , new Map
            ( [ [ 'd', 3 ]
              , [ 'e', 4 ]
              , [ 'f'
                , new Map ([[ 'g', 6 ]])
                ]
              ]
            )
        ]
      ]
    )
    
const toObject = (map = new Map) =>
  Object.fromEntries
    ( Array.from
        ( map.entries()
        , ([ k, v ]) =>
            v instanceof Map
              ? [ k, toObject (v) ]
              : [ k, v ]
        )
    )
    
console .log (toObject (m))
// { a: 1
// , b: 2
// , c:
//     { d: 3
//     , e: 4
//     , f: { g: 6 }
//     }
// }

否则,如果 Map 键是复杂对象并且不能可靠地强制转换为字符串,您将不得不提出另一个保留键的实际值的映射,例如 -

const m =
  new Map
    ( [ [ 'a', 1 ]
      , [ 'b', 2 ]
      , [ 'c'
        , new Map
            ( [ [ 'd', 3 ]
              , [ 'e', 4 ]
              , [ 'f'
                , new Map ([[ 'g', 6 ]])
                ]
              ]
            )
        ]
      ]
    )
    
const toObject = (map = new Map) =>
  Array.from
    ( map.entries()
    , ([ k, v ]) =>
        v instanceof Map
          ? { key: k, value: toObject (v) }
          : { key: k, value: v }
    )
    
console .log (toObject (m))
// [ { key: "a", value: 1 }
// , { key: "b", value: 2 }
// , { key: "c"
//   , value:
//       [ { key: "d", value: 3 }
//       , { key: "e", value: 4 }
//       , { key: "f", value: [ { key: "g", value: 6 } ] }
//       ]
//   }
// ]

【讨论】:

  • 第二种解决方案对我有用。谢谢@user633183
  • 如果地图包含地图数组作为值,则不确定这是否有效。
【解决方案2】:

如果地图中的值可以是你需要的地图数组:

const toObject = (map = new Map) => {
  if (!(map instanceof Map)) return map
  return Object.fromEntries(Array.from(map.entries(), ([k, v]) => {
    if (v instanceof Array) {
      return [k, v.map(toObject)]
    } else if (v instanceof Map) {
      return [k, toObject(v)]
    } else {
      return [k, v]
    }
  }))
}

【讨论】:

    猜你喜欢
    • 2022-01-14
    • 2019-10-03
    • 1970-01-01
    • 2011-12-09
    • 2022-12-18
    • 2018-01-24
    • 1970-01-01
    • 2019-05-14
    相关资源
    最近更新 更多