【问题标题】:Convert js Array to Dictionary/Hashmap将 js 数组转换为字典/哈希图
【发布时间】:2018-11-20 23:41:41
【问题描述】:

我正在尝试将对象数组转换为哈希图。我只有部分 ES6 可用,我也不能使用 Map

数组中的对象非常简单,例如{nation: {name: string, iso: string, scoringPoints: number}。我需要按scoringPoints 对它们进行排序。 我现在想要一个按 iso 排名的“字典” -> {[iso:string]:number}

我已经尝试过(来自here (SO)

const dict = sortedData.reduce((prev, curr, index, array) => (
    { ...array, [curr.nation.iso]: ++index }
), {});

dict 原来是一个Object,其索引以0 开头。希望只是我没有看到的一件小事。但目前我的头脑正在旋转如何将一个简单的数组转换为一个类似 hashmap 的对象。 也许Array.map

我还应该注意,我使用的是TypeScript,之前我在输入不正确时也遇到了一些麻烦。

const test = [
    { nation: { name: "Germany", iso: "DE", rankingPoints: 293949 } },
    { nation: { name: "Hungary", iso: "HU", rankingPoints: 564161 } },
    { nation: { name: "Serbia", iso: "SR", rankingPoints: 231651 } }
];

const sorted = test.sort((a, b) => a.nation.rankingPoints - b.nation.rankingPoints);
const dict = sorted.reduce((prev, curr, index, array) => ({ ...array, [curr.nation.iso]: ++index }), {});
console.log(JSON.stringify(dict));  

正在显示

{
    "0": {
        "nation": {
            "name": "Serbia",
            "iso": "RS",
            "rankingPoints": 231651
        }
    },
    "1": {
        "nation": {
            "name": "Germany",
            "iso": "DE",
            "rankingPoints": 293949
        }
    },
    "2": {
        "nation": {
            "name": "Hungary",
            "iso": "HU",
            "rankingPoints": 564161
        }
    },
    "HU": 3
}

在控制台中。

根据 cmets,我想要的是类似 hashmap 的对象

{
    "HU": 1,
    "DE": 2,
    "RS": 3
}

其中属性值是排序数据中的排名 (+1),因此我可以通过访问 dict["DE"] 来简单地获得排名,这将返回 2

【问题讨论】:

  • 请张贴输入输出示例。
  • @amrendersingh 添加了一些测试数据和它给出的输出
  • 我们需要知道您想要的输出。你希望代码做什么。
  • @KingKerosin 你想将 iso 映射到排名点吗?
  • @amrendersingh。没有。 Iso 排名(通过rankingpoints 的排序计算得出)。更新了问题以显示我想要的内容

标签: javascript typescript


【解决方案1】:

使用forEachreduce 捕获数据中每个键的位置:

const test = [
    { nation: { name: "Germany", iso: "DE", rankingPoints: 293949 } },
    { nation: { name: "Hungary", iso: "HU", rankingPoints: 564161 } },
    { nation: { name: "Serbia", iso: "SR", rankingPoints: 231651 } }
];    

const sorted = test.sort((a, b) => a.nation.rankingPoints - b.nation.rankingPoints);

// Using forEach:

var dict = {}
sorted.forEach((el, index) => dict[el.nation.iso] = sorted.length - index);

// Using reduce:

dict = sorted.reduce(
    (dict, el, index) => (dict[el.nation.iso] = sorted.length - index, dict),
    {}
);

console.log(dict)
console.log("dict['DE'] = ", dict['DE'])

输出:

{
  "SR": 3,
  "DE": 2,
  "HU": 1
}
dict['DE'] =  2

(请注意,在用作地图的对象中,属性的顺序并不重要 - 如果您需要特定的顺序,请使用数组。)

【讨论】:

  • 谢谢。使用reduce 风格,因为我是单线的粉丝;)顺序是这里的重点,因为我只是希望它显示排名。但是可以通过之前排序的Array 上的idx 参数来执行此操作。
【解决方案2】:

const test = [
  { nation: { name: "Germany", iso: "DE", rankingPoints: 293949 } },
  { nation: { name: "Hungary", iso: "HU", rankingPoints: 564161 } },
  { nation: { name: "Serbia", iso: "SR", rankingPoints: 231651 } }
];

const sorted = test.sort((a, b) =>  b.nation.rankingPoints - a.nation.rankingPoints);
const dict = sorted.reduce((result, curr, index, array) => ({ ...result, [curr.nation.iso]: ++index }), {});
console.log(JSON.stringify(dict)); 

【讨论】:

    【解决方案3】:

    也可以使用 Array.map 和 Object.fromEntries 来实现:

    const test = [
      { nation: { name: "Germany", iso: "DE", rankingPoints: 293949 } },
      { nation: { name: "Hungary", iso: "HU", rankingPoints: 564161 } },
      { nation: { name: "Serbia", iso: "SR", rankingPoints: 231651 } }
    ];
    
    const sorted = test.sort((a, b) => a.nation.rankingPoints < b.nation.rankingPoints ? 1 : (a.nation.rankingPoints > b.nation.rankingPoints ? -1 : 0));
    
    const dict = Object.fromEntries(sorted.map((c, index) => [c.nation.iso, index + 1]));
    
    console.log(dict);

    【讨论】:

      猜你喜欢
      • 2019-10-27
      • 2019-05-23
      • 2012-10-29
      • 2018-07-18
      • 1970-01-01
      • 2020-01-26
      • 2017-06-20
      • 2011-07-16
      • 1970-01-01
      相关资源
      最近更新 更多