【问题标题】:How do I reduce a javascript string array to unique values but keep count of the number of duplicates?如何将 javascript 字符串数组减少为唯一值但保留重复次数?
【发布时间】:2021-03-26 03:26:55
【问题描述】:

我有一个包含许多字符串的数组,比如这个:

["e", "e", "e", "e", "a", "e", "e", "a", "e", "e", "e", "e", "e", "o", "a", "e", "r", "e", "e", "e", "o", "e", "u"]

现在我想减少这个数组,使它只包含唯一的字符串。同时,我想计算重复次数并(最好)计算一个百分比,显示重复次数除以字符串总数。

我正在考虑一个看起来像这样的最终结果:

[
    {
        letter: "e",
        duplicates: 16,
        percentage: 0.695652173913043
    },
    {
        letter: "a",
        duplicates: 3,
        percentage: 0.130434782608696
    },
    {
        letter: "o",
        duplicates: 2,
        percentage: 0.08695652173913
    },
    {
        letter: "r"
        duplicates: 1,
        percentage: 0.043478260869565
    },
    {
        letter: "u",
        duplicates: 1,
        percentage: 0.043478260869565
    }
]

我将如何在 JavaScript/ES6 中进行这种转换?

【问题讨论】:

  • 你为此做了什么尝试,这看起来像是一项需要答案的学校作业?
  • 请访问help center,使用tour查看内容和How to Ask。做一些研究,搜索关于 SO 的相关主题;如果您遇到困难,请发布您尝试的minimal reproducible example,注意输入和预期输出,最好在Stacksnippet
  • 这不是学校作业(我快 50 岁了)。这是我正在进行的语言实验的一部分。这也是一个有趣的问题,我认为 StackOverflow 社区会很感激。我知道我拥有什么以及我想得到什么,我只是需要一些帮助才能到达那里。

标签: javascript arrays ecmascript-6 reduce


【解决方案1】:

let array = ["e", "e", "e", "e", "a", "e", "e", "a", "e", "e", "e", "e", "e", "o", "a", "e", "r", "e", "e", "e", "o", "e", "u"]


let result = [...new Set(array)].map(e =>({letter:e,
duplicates:array.filter(n => n===e).length,
percentage:array.filter(n => n===e).length/array.length}))


console.log(result)

【讨论】:

  • 谢谢!这对我的问题也是一个很好的解决方案!我看到你将扩展语法与 Set 一起使用,这是我一直在尝试的东西,尽管我还没来得及。
  • @tkahn 这实际上是对 spread 的浪费,因为它创建了一个中间数组,只是为了在其上调用 .map,这会创建 另一个 数组。 Array.from(new Set(array), e => ...) 是写[...new Set(array)].map(e => ...) 的正确方法
【解决方案2】:

这可以通过使用Array#fromArray#reduceMapArray#mapdestructuring 来实现。

reduce 允许重新组合和计算字母及其出现次数。 正确组织它们后,您就可以继续绘制所有结果并计算百分比。

const data = ["e", "e", "e", "e", "a", "e", "e", "a", "e", "e", "e", "e", "e", "o", "a", "e", "r", "e", "e", "e", "o", "e", "u"];

const res = Array
  .from(data.reduce((acc, cur) => acc.set(cur, (acc.get(cur)||0) + 1), new Map()))
  .map(([letter, duplicates]) => ({letter, duplicates, percentage: duplicates / data.length}));
  
 console.log(res);

【讨论】:

  • 非常感谢!发生了很多事情,所以我需要一些时间来阅读它以了解正在发生的一切,但它就像一个魅力!
  • @tkahn np,如果您需要更详细的版本,请告诉我。这是最大的缩影。
  • Array.from 接受映射参数,即Array.from(data.reduce(...), ([ letter, duplicates ]) => ...) 会在一半的迭代中做同样的事情
  • @ThankYou 感谢您的建议,但我不相信它会使迭代减半。 “更清楚一点,Array.from(obj, mapFn, thisArg) 与 Array.from(obj).map(mapFn, thisArg) 的结果相同,只是它不创建中间数组。”
  • 它确实将迭代减半,因为Array.from 第一次遍历 Map 条目,创建中间数组,然后 Array#map 对中间数组进行第二次遍历,创建第二个数组。 Array.from(myMap, mappingFn) 一次性完成。
猜你喜欢
  • 1970-01-01
  • 2016-08-07
  • 2017-09-19
  • 2017-06-12
  • 1970-01-01
  • 2019-03-29
  • 2014-11-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多