【问题标题】:Accumulating a Map from an Array In TypeScript在 TypeScript 中从数组中累积映射
【发布时间】:2019-12-18 04:26:35
【问题描述】:

我有一个 TypeScript 对象数组,其形状基本上如下:

interface MyObject {
  id: string
  position: number
}

我正在尝试将此数组转换为 id 映射到位置,对于 JSON POST 如下所示:

{ 
   "id1": 1,
   "id2": 2,
}

一种方法是使用 ES6 Map

array.reduce((map, obj) => map.set(obj.id, obj.position), new Map())

这可行,但是将 ES6 Map 转换为 JSON 是有问题的。

我曾尝试将键值对累积为纯对象字面量,但 TypeScript 一直讨厌我尝试的一切,包括 Indexable TypesObject.create({}) 和许多其他想法。

如何从对象数组中提取键值对的纯对象字面量?

【问题讨论】:

  • 我认为将数字写成字符串可能会解决您的问题,例如1 --> "1"
  • Object.create(null) 将是正确的 Map 等效项。

标签: javascript arrays json typescript ecmascript-6


【解决方案1】:

如果你的目标环境支持 ES2019,你可以使用Object.fromEntries(),像这样:

function arrToObjES2019(arr: MyObject[]) {
  return Object.fromEntries(arr.map(({ id, position }) => [id, position]));
}

或者,如果没有,您可以在空对象上使用数组 reduce() 制作您自己的类似 polyfill 的 Object.fromEntries() 版本,如下所示:

function fromEntries<V>(iterable: Iterable<[string, V]>) {
  return [...iterable].reduce((obj, [key, val]) => {
    obj[key] = val
    return obj
  }, {} as {[k: string]: V})
}

然后使用它:

function arrToObj(arr: MyObject[]) {
  return fromEntries(arr.map(({ id, position }) => [id, position]));
}

无论哪种方式都应该让你做你想做的事:

const arr: MyObject[] = [
  { id: "id1", position: 1 },
  { id: "id2", position: 2 }
];

console.log(JSON.stringify(arrToObj(arr))); // {"id1":1,"id2":2}

好的,希望对您有所帮助。祝你好运!

Link to code

【讨论】:

  • 感谢您向我展示 fromEntries. 作为旁注 FWIW,因为我想输入 JSON 请求,所以 @jcalz 的解决方案生成的类型是 [index: string]: number,以防您好奇。所以我觉得可索引类型与解决方案有一些小的相关性。
【解决方案2】:

我不确定为什么 reduce 不是这里的方法...

array.reduce((acc, val) => 
   Object.assign(acc, {[val.id]: val.position}), {});

【讨论】:

    猜你喜欢
    • 2021-06-22
    • 2014-07-12
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多