如何在TypeScript中计算字符串数组中的字符串出现次数?[副本]

qzlgjiam  于 2023-06-30  发布在  TypeScript
关注(0)|答案(3)|浏览(353)

此问题已在此处有答案

Counting the occurrences / frequency of array elements(41答案)
15小时前关门了。
我需要迭代一个字符串数组,计算每个字符串的出现次数,并返回一个包含值和出现次数的对象。
我试图使用数组reduce函数来实现这样的事情,但是,尽管尝试了,我还没有能够实现这一点。
所以我有以下内容:

["tony", "tony", "tony", "tony", "kassandra", "tony", "tony", "kassandra"]

我需要输出:

[{ name: "tony", matches: 6 }, { name: "kassandra", matches: 2 }]

我应该使用什么来获得上述输出?
我尝试了以下方法:

const names = nameList.map((user) => user.name);

const reduce = names.reduce((p, c) => {
  if (p == c) {
    return { name: p, matches: `idk what put here yet` };
  }
  return c;
});
l7wslrjt

l7wslrjt1#

首先,计算数组中每个名称的出现次数。
其次,将其转换为具有所需格式name及其matches的对象。

const names = ["tony", "tony", "tony", "tony", "kassandra", "tony", "tony", "kassandra"];
const counts = {};
//1.
names.forEach(name => {
  if (counts[name]) {
    counts[name] += 1;
  } else {
    counts[name] = 1;
  }
});
//2.
const result = Object.keys(counts).map(name => {
  return {
    name: name,
    matches: counts[name]
  };
});
console.log(result);

如果你想使用.reduce()方法来计算名字的出现次数:

const counts = names.reduce((acc, name) => {
    acc[name] = (acc[name] || 0) + 1;
    return acc;
  }, {});

另一种使用Object.entries()将示例转换回对象的方法

Object.entries(counts).map(([name, matches]) => ({ name, matches }));

两种方法相结合:

const names = ["tony", "tony", "tony", "tony", "kassandra", "tony", "tony", "kassandra"];
const counts = names.reduce((acc, name) => {
    acc[name] = (acc[name] || 0) + 1;
    return acc;
  }, {});
const result = Object.entries(counts).map(([name, matches]) => ({ name, matches }));
console.log(result);
yfjy0ee7

yfjy0ee72#

要获得所需的输出,可以使用reduce函数沿着一个对象来存储每个名称的计数。下面是一个如何实现它的示例:

const nameList = ["tony", "tony", "tony", "tony", "kassandra", "tony", "tony", "kassandra"];

const countMatches = nameList.reduce((acc, curr) => {
  if (acc[curr]) {
    acc[curr]++;
  } else {
    acc[curr] = 1;
  }
  return acc;
}, {});

const result = Object.entries(countMatches).map(([name, matches]) => ({ name, matches }));

console.log(result);

输出:

[
  { name: 'tony', matches: 6 },
  { name: 'kassandra', matches: 2 }
]

在上面的代码中,reduce函数用于迭代nameList数组。accumulator(acc)是一个跟踪每个名称的计数的对象。如果当前名称(curr)已作为属性存在于累加器中,则计数将递增1。否则,将创建一个新属性,并将名称作为键,初始计数为1。
reduce操作之后,我们使用Object.entries将对象转换回键值对数组。然后,我们使用map将每个键值对转换为具有namematches属性的对象。最后,结果存储在result变量中。
注意:在您尝试的代码中,您使用相等运算符(==)比较pc,该运算符只比较值,而不比较出现次数。此外,您没有处理名称与前一个名称不相等的情况。

trnvg8h3

trnvg8h33#

一个纯Array::reduce() Typescript解决方案。
我们提供了一个聚合对象(回调中的r),其中存储了2个值:结果数组arr与所需的输出和Mapmap,我们可以很容易地找到一个现有的数组项,以增加找到的匹配:
A live typescript gist is here.

const names = ["tony", "tony", "tony", "tony", "kassandra", "tony", "tony", "kassandra"];

interface MatchItem {
  name: string, 
  matches: number
};

const result = names.reduce((r, name) => {
  const {arr, map} = r;
  const item = map.get(name);
  item ? item.matches++ : map.set(name, arr[arr.length] = { name, matches: 1 });
  return r;
}, { arr: [], map: new Map } as {arr: MatchItem[], map: Map<string, MatchItem>}).arr;

console.log(result);

JS版本:

const names = ["tony", "tony", "tony", "tony", "kassandra", "tony", "tony", "kassandra"];

const result = names.reduce((r, name) => {
  const {arr, map} = r;
  const item = map.get(name);
  item ? item.matches++ : map.set(name, arr[arr.length] = { name, matches: 1 });
  return r;
}, { arr: [], map: new Map }).arr;

console.log(result);

还有一个基准:

<script benchmark data-count="1">

// randomly fill with names
const src = 'tony kassandra alex peter mike arnold tina maria stephen nicolas samuel sonya natali elena julia'.split(' ');

let i = 16000000;
const names = [];
while (i--) {
    names.push(src[Math.floor(Math.random() * src.length)]);
}

// @benchmark XMehdi01's solution
const counts = names.reduce((acc, name) => {
    acc[name] = (acc[name] || 0) + 1;
    return acc;
}, {});
Object.entries(counts).map(([name, matches]) => ({ name, matches }));

//@benchmark Alexander's solution
names.reduce((r, name) => {
    const {arr, map} = r;
    const item = map.get(name);
    item ? item.matches++ : map.set(name, arr[arr.length] = { name, matches: 1 });
    return r;
}, { arr: [], map: new Map }).arr;

</script>
<script src="https://cdn.jsdelivr.net/gh/silentmantra/benchmark/loader.js"></script>

相关问题