列表中单词出现的次数,不区分大小写

count of word occurrences in a list, case insensitive

使用普通 javascript 获取数组中包含的不同单词的 不区分大小写 计数的最专业方法是什么?自己第一次尝试,感觉不够专业

我希望结果是 Map

您可以使用 Array.reduce 将每个单词存储为 属性 并将每个单词的出现作为值。

在reducer函数中,检查字母(转换为小写)是否作为属性存在。如果不是,则将其值设置为 1。否则,增加 属性 值。

const arr = ["a", "A", "b", "B"]

const result = arr.reduce((a,b) => {
  let c = b.toLowerCase();
  return a[c] = a[c] ? ++a[c] : 1, a;
}, {})

console.log(result)
作为一个班轮:const result = arr.reduce((a,b) => (c = b.toLowerCase(), a[c] = a[c] ? ++a[c] : 1, a), {})

将其转换为 Map, you can use Object.entries (sugged by @Théophile):

const arr = ["a", "A", "b", "B"]

const result = arr.reduce((a, b) => {
  let c = b.toLowerCase();
  return a[c] = a[c] ? ++a[c] : 1, a;
}, {})

const m = new Map(Object.entries(result))
m.forEach((value, key) => console.log(key, ':', value))

使用 set 去除重复项,并使用展开运算符将其放回数组中。

const  myarray = ['one', 'One', 'two', 'TWO', 'three'];
const noDupes = [... new Set( myarray.map(x => x.toLowerCase()))];
console.log(noDupes);

您可以使用一个对象来存储结果,然后通过将该对象传递给 Object.entries

来创建一个 Map 对象

const arr = ["c", "A", "C", "B", "b"];

const counts = {};
for (const el of arr) {
  let c = el.toLowerCase();
  counts[c] = counts[c] ? ++counts[c] : 1;
}

console.log(counts);

const map = new Map(Object.entries(counts))
map.forEach((k,v) => console.log(k,v))

虽然接受的 'group-by' 操作很好,但它没有解决 case-insensitive/unicode 比较的复杂性。

首先,您可以直接减少到 Map,这里按原样计算字符,而不考虑不区分大小写或 unicode 变化导致从数组中计算出 20 'distinct' 个字符长度为 24.

const input = [ 'a', 'A', 'b', 'B', '\u00F1', '\u006E\u0303', 'İ', 'i', 'Gesäß',
  'GESÄSS', '\u0399', '\u1FBE', '\u00E5', '\u212B', '\u00C5', '\u212B', '\u0399', '\u1FBE', '\u03B9', '\u1FBE', '\u03B2', '\u03D0', '\u03B5', '\u03F5', ];

const result = input.reduce((a, b) => a.set(b, (a.get(b) ?? 0) + 1), new Map());

console.log('distinct count: ', result.size); console.log('Map(',result.size,') {', [...result.entries()].map(([k, v]) => `${k} => ${v}`).join(', '), '}');

根据下面的示例,产生最紧凑计数的方法是使用 word.normalize().toLocaleUpperCase() 并传递土耳其 ('tr') 作为此特定示例数组的语言环境。它导致从长度为 24 的数组中计算出 9 个 'distinct' 个字符,正确处理 ñ 的不同编码,Gesäß(GESÄSS) 的等效拼写,并考虑语言环境具体案例更改(iİ

const input = [ 'a', 'A', 'b', 'B', '\u00F1', '\u006E\u0303', 'İ', 'i', 'Gesäß',
  'GESÄSS', '\u0399', '\u1FBE', '\u00E5', '\u212B', '\u00C5', '\u212B', '\u0399', '\u1FBE', '\u03B9', '\u1FBE', '\u03B2', '\u03D0', '\u03B5', '\u03F5', ];

const result_normalize_locale = input.reduce((a, b) => {
  const w = b.normalize().toLocaleUpperCase('tr');

  return a.set(w, (a.get(w) ?? 0) + 1);
}, new Map());

console.log('distinct count: ', result_normalize_locale.size); console.log('Map(',result_normalize_locale.size,') {', [...result_normalize_locale.entries()].map(([k, v]) => `${k} => ${v}`).join(', '), '}');

使用这个简单的 'group-by' 我们可以查看可用案例比较方法之间的差异:toLowerCase(), toLocaleLowerCase(), toUpperCase(), and toLocaleUpperCase() and unicode variations can be accounted for using normalize()

小写

toLowerCase() – 15 'distinct' 个字符。

toLocaleLowerCase() – 14 'distinct' 个字符,在本例中指定土耳其 ('tr') 作为语言环境。

normalize().toLocaleLowerCase() – 12 'distinct' 个字符,再次以 'tr' 作为语言环境。

const input = [ 'a', 'A', 'b', 'B', '\u00F1', '\u006E\u0303', 'İ', 'i', 'Gesäß',
  'GESÄSS', '\u0399', '\u1FBE', '\u00E5', '\u212B', '\u00C5', '\u212B', '\u0399', '\u1FBE', '\u03B9', '\u1FBE', '\u03B2', '\u03D0', '\u03B5', '\u03F5', ];
// ['a', 'A', 'b', 'B', 'ñ', 'ñ', 'İ', 'i', 'Gesäß', 'GESÄSS', 'Ι', 'ι', 'å', 'Å', 'Å', 'Å', 'Ι', 'ι', 'ι', 'ι', 'β', 'ϐ', 'ε', 'ϵ', ]
// input.length: 24

// grouping by toLowerCase()
const result = input.reduce((a, b) => {
  const w = b.toLowerCase();

  return a.set(w, (a.get(w) ?? 0) + 1);
}, new Map());

// grouping by toLocaleLowerCase('tr') [Turkey]
const result_locale = input.reduce((a, b) => {
  const w = b.toLocaleLowerCase('tr');

  return a.set(w, (a.get(w) ?? 0) + 1);
}, new Map());

// grouping by normalize().toLocaleLowerCase('tr') [Turkey]
const result_normalize_locale = input.reduce((a, b) => {
  const w = b.normalize().toLocaleLowerCase('tr');

  return a.set(w, (a.get(w) ?? 0) + 1);
}, new Map());

// log toLowerCase() result - 15 'distinct' characters
console.log('toLowerCase() '); console.log('distinct count: ', result.size); console.log('Map(',result.size,') {', [...result.entries()].map(([k, v]) => `${k} => ${v}`).join(', '), '}');

// log toLocaleLowerCase('tr') result - 14 'distinct' characters
console.log("\ntoLocaleLowerCase('tr')"); console.log('distinct count: ', result_locale.size); console.log('Map(',result_locale.size,') {', [...result_locale.entries()].map(([k, v]) => `${k} => ${v}`).join(', '), '}');

// log normalize().toLocaleLowerCase('tr') result - 12 'distinct' characters
console.log("\nnormalize().toLocaleLowerCase('tr')"); console.log('distinct count: ', result_normalize_locale.size); console.log('Map(',result_normalize_locale.size,') {', [...result_normalize_locale.entries()].map(([k, v]) => `${k} => ${v}`).join(', '), '}');
.as-console-wrapper { max-height: 100% !important; top: 0; }

转大写

toUpperCase() – 12 'distinct' 个字符。

toLocaleUpperCase() – 11 'distinct' 个字符,在本例中指定土耳其 ('tr') 作为语言环境。

normalize().toLocaleUpperCase() – 9 'distinct' 个字符,再次以 'tr' 作为语言环境。

const input = [ 'a', 'A', 'b', 'B', '\u00F1', '\u006E\u0303', 'İ', 'i', 'Gesäß',
  'GESÄSS', '\u0399', '\u1FBE', '\u00E5', '\u212B', '\u00C5', '\u212B', '\u0399', '\u1FBE', '\u03B9', '\u1FBE', '\u03B2', '\u03D0', '\u03B5', '\u03F5', ];
// ['a', 'A', 'b', 'B', 'ñ', 'ñ', 'İ', 'i', 'Gesäß', 'GESÄSS', 'Ι', 'ι', 'å', 'Å', 'Å', 'Å', 'Ι', 'ι', 'ι', 'ι', 'β', 'ϐ', 'ε', 'ϵ', ]
// input.length: 24

// grouping by toUpperCase() 
const result = input.reduce((a, b) => {
  const w = b.toUpperCase();

  return a.set(w, (a.get(w) ?? 0) + 1);
}, new Map());

// grouping by toLocaleUpperCase('tr') [Turkey]
const result_locale = input.reduce((a, b) => {
  const w = b.toLocaleUpperCase('tr');

  return a.set(w, (a.get(w) ?? 0) + 1);
}, new Map());

// grouping by normalize().toLocaleUpperCase('tr') [Turkey]
const result_normalize_locale = input.reduce((a, b) => {
  const w = b.normalize().toLocaleUpperCase('tr');

  return a.set(w, (a.get(w) ?? 0) + 1);
}, new Map());

// log toUpperCase() result - 12 'distinct' characters
console.log('toUpperCase() '); console.log('distinct count: ', result.size); console.log('Map(',result.size,') {', [...result.entries()].map(([k, v]) => `${k} => ${v}`).join(', '), '}');

// log toLocaleUpperCase('tr') result - 11 'distinct' characters
console.log("\ntoLocaleUpperCase('tr')"); console.log('distinct count: ', result_locale.size); console.log('Map(',result_locale.size,') {', [...result_locale.entries()].map(([k, v]) => `${k} => ${v}`).join(', '), '}');

// log normalize().toLocaleUpperCase('tr') result - 9 'distinct' characters
console.log("\nnormalize().toLocaleUpperCase('tr')"); console.log('distinct count: ', result_normalize_locale.size); console.log('Map(',result_normalize_locale.size,') {', [...result_normalize_locale.entries()].map(([k, v]) => `${k} => ${v}`).join(', '), '}');
.as-console-wrapper { max-height: 100% !important; top: 0; }