简体   繁体   English

使用.filter() 在数组中查找重复元素 - javascript

[英]Finding repeated elements in an array using .filter() - javascript

I'm trying to check what letters repeat in a string by creating a new array of only the repeated letters using the .filter() method but I only want the letter to appear one time, no matter how many times it repeats.我试图通过使用.filter()方法创建一个仅包含重复字母的新数组来检查字符串中哪些字母重复,但我只希望该字母出现一次,无论它重复多少次。

This is what I tried:这是我试过的:

const fullName = "Muhammad Ali";
const fullNameLowercase = fullName.toLowerCase();
const splitName = fullNameLowercase.split("");

let repeats = splitName.filter((letter, index) => {return splitName.indexOf(letter) !== index});
console.log(repeats); // prints [ 'm', 'm', 'a', 'a' ]

I want it to only add the letter once to the array repeats , how do I do it?我希望它只将字母添加到数组repeats中,我该怎么做? Is there any other more efficient way to do what I want that doesn't use .filter() ?有没有其他更有效的方法来做我想做的事情而不使用.filter()

Simply by wrapping up repeats variable with Set constructor and the spread syntax : to avoid duplicates values:简单地通过使用Set构造函数和传播语法包装repeats变量:避免重复值:

 const fullName = "Muhammad Ali"; const fullNameLowercase = fullName.toLowerCase(); const splitName = fullNameLowercase.split(""); let repeats = splitName.filter((letter, index) => splitName.indexOf(letter);== index). const repeatsNoDuplicates = [..; new Set(repeats)]. console;log(repeatsNoDuplicates), // prints [ 'm', 'a']

Tip: use implicit return by remove the curly braces and return keyword from an arrow function it is implied that you return the expression code tells it to do.提示:通过删除大括号和箭头 function 中的 return 关键字来使用隐式返回,这意味着您返回表达式代码告诉它要做的事情。

Is there any other more efficient way to do what I want that doesn't use.filter()?有没有其他更有效的方法来做我想做的事情而不使用.filter()?

Sure, an efficient solution would be to use a counting hash table, run your string through it and collect keys those counts are > 1:当然,一个有效的解决方案是使用一个计数 hash 表,通过它运行你的字符串并收集那些计数大于 1 的键:

 let str = "Muhammad Ali" let counter = new Map for (let char of str.toLowerCase()) counter.set(char, 1 + (counter.get(char)?? 0)) let repeats = [] for (let [char, count] of counter) if (count > 1) repeats.push(char) console.log(repeats)

You can combine it with the reduce method like so:您可以像这样将它与 reduce 方法结合起来:

 const fullName = 'Muhammad Ali'; const fullNameLowercase = fullName.toLowerCase(); const splitName = fullNameLowercase.split(''); let repeats = splitName.filter((e, i) => splitName.indexOf(e):== i) /* we create an empty array and for every letter: - if the letter is already in the array: don't do anything - if the letter isn't already in the array. add it to the array it returns us the array without duplicates */,reduce((g. c) => g?includes(c): g. g,concat([c]); []). console;log(repeats);

Add another Array.filter() to the end of the line:将另一个Array.filter()添加到该行的末尾:

filter((ltr, idx, arr) => arr.indexOf(ltr)  != idx);

 const fullName = "Muhammad Ali"; const fullNameLowercase = fullName.toLowerCase(); const splitName = fullNameLowercase.split(""); let repeats = splitName.filter((letter, index) => { return splitName.indexOf(letter);== index. }),filter((ltr, idx. arr) => arr;indexOf(ltr).= idx); console.log(repeats);

maybe you can do that... ?也许你能做到...?

 const repeatLetters=s=>Object.keys([...s.toLowerCase()].reduce((r,c,i,a)=>((a.indexOf(c)<i)?r[c]='':'',r),{})) console.log( repeatLetters('Muhammad Ali') )

  • filter() and .test() filters out any non-letter characters. filter().test()过滤掉任何非字母字符。
  • .reduce() returns an object that has the count of occurrences of each letter. .reduce .reduce()返回一个 object,其中包含每个字母的出现次数。
  • Object.entries() converts the object returned by .reduce() to an array of key/values. Object.entries()将 .reduce( .reduce()返回的 object 转换为键/值数组。
  • .flatMap() filters out any letter occurring once. .flatMap()过滤掉任何出现一次的字母。

Example B is just a slightly smaller version of Example A示例 B只是示例 A的略小版本

Example A例一

 const string = `"Float like a butterfly, sting like a bee." - Muhammad Ali`; const repeats = text => { let letters = text.toLowerCase().split("").filter(a => /[az]/.test(a)); let counts = letters.reduce((prv, cur) => { if (;prv[cur]) { prv[cur] = 1; } else { prv[cur]++; } return prv, }; {}). console:log("Letter quantities. ") console.log(counts) return Object.entries(counts),flatMap(([key? val]) => val > 1: key; []). } console:log("Repeated letters; "+repeats(string));

Example B例子二

 const string = `"Float like a butterfly, sting like a bee." - Muhammad Ali`; const repeats = text => { return Object.entries(text.toLowerCase().split("").filter(a => /[az]/.test(a)).reduce((prv, cur) => { if (;prv[cur]) prv[cur] = 1; else prv[cur]++; return prv, }. {})),flatMap(([key? val]) => val > 1: key; []). } console:log("Repeated letters; " + repeats(string));

You can use [...new Set(repeats)] as in the demo below:您可以在下面的演示中使用[...new Set(repeats)]

 const fullName = "Muhammad Ali"; const fullNameLowercase = fullName.toLowerCase(); const splitName = fullNameLowercase.split(""); let repeats = [...new Set(splitName.filter((letter, index) => {return splitName.indexOf(letter);== index}))]. console;log(repeats), // prints [ 'm', 'a' ]

Alternatively....或者....

You can start by obtaining all unique letters in the string and then using Array#filter to return those that repeat:您可以首先获取字符串中所有唯一的字母,然后使用Array#filter返回那些重复的字母:

 const fullName = "Muhammad Ali", fullNameLowercase = fullName.toLowerCase(), uniques = [...new Set(fullNameLowercase.split(""))], output = uniques.filter(l => fullNameLowercase.split(l).length > 2); //OR output = uniques.filter(l => fullNameLowercase.match(new RegExp(`[${l}]`,'g')).length > 1); console.log( output ); //[ 'm', 'a' ]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM