Filtrer anagrammer
Anagrams er ord der har det samme antal individuelle tegn men i en anden rækkefølge.
For eksempel:
nap - pan
ear - are - era
cheaters - hectares - teachers
Skriv en funktion aclean(arr) der returnerer et array renset for anagrammer.
For eksempel:
let arr = ["nap", "teachers", "cheaters", "PAN", "ear", "era", "hectares"];
alert( aclean(arr) ); // "nap,teachers,ear" eller "PAN,cheaters,era"
Fra hvert anagramgruppe skal der kun være ét ord tilbage, uanset hvilket.
For at finde alle anagrammer kan vi opdele hvert ord i bogstaver og sortere dem. Når bogstaverne er sorteret, er alle anagrammer ens.
For eksempel:
nap, pan -> anp
ear, era, are -> aer
cheaters, hectares, teachers -> aceehrst
...
Vi bruger de bogstav-sorterede varianter som map-nøgler for kun at gemme én værdi per nøgle:
function aclean(arr) {
let map = new Map();
for (let word of arr) {
// opsplit ordet i bogstaver, sorter dem og sæt dem sammen igen
let sorted = word.toLowerCase().split('').sort().join(''); // (*)
map.set(sorted, word);
}
return Array.from(map.values());
}
let arr = ["nap", "teachers", "cheaters", "PAN", "ear", "era", "hectares"];
alert( aclean(arr) );
Bogstav-sortering udføres af kæden af kald i linjen (*).
For nemheds skyld deler vi det op i flere linjer:
let sorted = word // PAN
.toLowerCase() // pan
.split('') // ['p','a','n']
.sort() // ['a','n','p']
.join(''); // anp
To forskellige ord 'PAN' og 'nap' får den samme bogstav-sorterede form 'anp'.
Næste linje sætter ordet ind i map’et med den bogstav-sorterede form som nøgle:
map.set(sorted, word);
Hvis vi nogensinde møder et ord med den samme bogstav-sorterede form igen, vil det overskrive den tidligere værdi med den samme nøgle i map’et. Så vi vil altid have højst ét ord per bogstav-form.
Til sidst tager Array.from(map.values()) en iterable over map-værdier (vi behøver ikke nøgler i resultatet) og returnerer et array af dem.
Her kunne vi også bruge et almindeligt objekt i stedet for Map, fordi nøglerne er strenge.
En løsning kan se sådan ud:
function aclean(arr) {
let obj = {};
for (let i = 0; i < arr.length; i++) {
let sorted = arr[i].toLowerCase().split("").sort().join("");
obj[sorted] = arr[i];
}
return Object.values(obj);
}
let arr = ["nap", "teachers", "cheaters", "PAN", "ear", "era", "hectares"];
alert( aclean(arr) );