首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JS:嵌套映射

问JS:嵌套映射
EN

Stack Overflow用户
提问于 2022-10-23 20:09:36
回答 1查看 56关注 0票数 -1

我试图在JavaScript中实现一个Wordle助手。我对JS很陌生,我确信下面这些都是微不足道的,但是地图仍然让我感到困惑。假设我有:

代码语言:javascript
复制
{
  'fight' => [ '02222', '02222', '02222', '02222', '20000' ],
  'eight' => [ '02222', '02222', '02222', '02222', '10000' ],
  'right' => [ '02222', '02222', '02222', '02222', '10000' ],
  'sight' => [ '02222', '02222', '02222', '02222', '10000' ],
  'night' => [ '02222', '02222', '02222', '02222', '10000' ],
  'ferns' => [ '20000', '01000', '00100', '00001', '00010' ]
}

如何以下列格式对唯一项目进行计数:

代码语言:javascript
复制
[{
    "fight": [1, 4],
    "eight": [1, 4],
    "right": [1, 4],
    "sight": [1, 4],
    "night": [1, 4],
    "ferns": [1, 1, 1, 1, 1]
}]

(如果数据结构不同,我会做得更好吗?)

(这些是计算值,所以我不知道data的键是什么,也不知道每个键有多少项。)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-23 21:00:57

编辑

要重新映射更新后的数据,在许多方面都比较简单。我假设您的语法表明您使用的是Map,而且由于映射不能有重复的键,所以您不需要“按组”,而只需在映射的entries上迭代,通过计数每个字符串中的非零字符来转换每个values数组。因为您还希望删除重复计数([1, 4]而不是[1, 4, 4, 4, 4]),所以可以在将每个值数组返回到数组之前为其创建一个中间Set,然后将其映射到计数字符。

​

代码语言:javascript
复制
const input = new Map([['fight', ['02222', '02222', '02222', '02222', '20000']], ['eight', ['02222', '02222', '02222', '02222', '10000']], ['right', ['02222', '02222', '02222', '02222', '10000']], ['sight', ['02222', '02222', '02222', '02222', '10000']], ['night', ['02222', '02222', '02222', '02222', '10000']], ['ferns', ['20000', '01000', '00100', '00001', '00010']]]);

// Map(6) {
//   'fight' => [ '02222', '02222', '02222', '02222', '20000' ],
//   'eight' => [ '02222', '02222', '02222', '02222', '10000' ],
//   'right' => [ '02222', '02222', '02222', '02222', '10000' ],
//   'sight' => [ '02222', '02222', '02222', '02222', '10000' ],
//   'night' => [ '02222', '02222', '02222', '02222', '10000' ],
//   'ferns' => [ '20000', '01000', '00100', '00001', '00010' ]
// }

const result = {};

for (const [key, values] of input.entries()) {
  result[key] = [...new Set(values)].map(s => s.match(/[^0]/g).length)
}

console.log(result)

​

我在这里使用带有正则表达式的String.match()来计数字符串中的非零位数,但是有很多替代方案,下面是我头顶上的两个数字:

代码语言:javascript
复制
// String#replaceAll()
'02222'.replaceAll('0', '').length;

// String#split() + filter()
'02222'.split('').filter(c => c !== '0').length;

原始答案

您的data示例留下了许多问题,既包括输入的形状,也包括您希望输出的内容。但不管怎么说,一个相当标准的“小组”似乎会起作用。

​

代码语言:javascript
复制
const data = [{ "fight": [{ "20000": 1, "02222": 4 }], "eight": [{ "10000": 1, "02222": 4 }], "right": [{ "20000": 1, "02222": 4 }], "sight": [{ "20000": 1, "02222": 4 }], "night": [{ "20000": 1, "02222": 4 }], "ferns": [{ "20000": 1, "01000": 1, "00100": 1, "00001": 1, "00010": 1 }] }];

const result = {};

for (const datum of data) {
  for (const [k, v] of Object.entries(datum)) {
    const values = v.flatMap(Object.values);
    (result[k] ??= [0]).push(...values);
    result[k][0] += values.length; // <-- This doesn't need to be stored, it is just the array.length (not including this element)
  }
}

console.log(result);

​

以上假设您可能有重复的键,并将结果扁平化为单个对象。如果data将包含多个对象,并且希望在这些范围内维护分组结果,则需要对每次迭代进行分组。(内部逻辑保持不变)

​

代码语言:javascript
复制
const data = [
  {
    "fight": [
      { "20000": 1, "02222": 4 },
      { "20000": 1, "01000": 1, "00100": 1, "00001": 1, "00010": 1 }
    ]
  },
  {
    "sight": [
      { "20000": 1, "02222": 4 }
    ],
    "night": [
      { "20000": 1, "02222": 4 },
      { "20000": 1, "02222": 4 }
    ]
  }
];

const result = [];

for (const datum of data) {
  const group = {}
  for (const [k, v] of Object.entries(datum)) {
    const values = v.flatMap(Object.values);
    (group[k] ??= [0]).push(...values);
    group[k][0] += values.length;
  }
  result.push(group)
}

console.log(result);

​

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74174414

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档