Duplicate Encoder (duplicate letters in a string)
The goal is to convert a string to a new string where each character in the new string is '(' if that character appears only once in the original string, or ')' if that character appears more than once in the original string. Ignore capitalization when determining if a character is a duplicate.
my problem is if it's repeating a letter first parenthese is showing wrong.
function duplicateEncode(word){
var repeat = [];
var result = [];
var letters = word.split('');
for (i=0; i < letters.length; i++){
if (repeat.indexOf(letters[i]) > -1) {
result.push(")");
} else {
result.push("(");
}
repeat.push(letters[i]);
}
return result.join("");
}
console.log(duplicateEncode("aleluia"))
"my problem is if it's repeating a letter first parenthesis is showing wrong."
This is because your code doesn't do any look-ahead, it only checks what characters have already been processed. One way or another you need to check if the current letter also appears earlier or later in the string.
The first way that came to mind was to start by counting all of the letters (putting the counts in an object), then map each letter based on its count. That way you only loop through the original word exactly twice:
function duplicateEncode(word){
var letterCount = {};
var letters = word.toLowerCase().split('');
letters.forEach(function(letter) {
letterCount[letter] = (letterCount[letter] || 0) + 1;
});
return letters.map(function(letter) {
return letterCount[letter] === 1 ? '(' : ')';
}).join('');
}
console.log(duplicateEncode("aleluia"))
console.log(duplicateEncode("AleLuia"))
console.log(duplicateEncode("No duplicates"))
console.log(duplicateEncode("All duplicated ALL DUPLICATED"))
Or the same thing with .reduce()
and arrow functions is only three lines:
function duplicateEncode(word){
const letters = word.toLowerCase().split('');
const counts = letters.reduce((ct, ltr) => ((ct[ltr] = (ct[ltr] || 0) + 1), ct), {});
return letters.map(letter => counts[letter] === 1 ? '(' : ')').join('');
}
console.log(duplicateEncode("aleluia"))
console.log(duplicateEncode("AleLuia"))
console.log(duplicateEncode("No duplicates"))
console.log(duplicateEncode("All duplicated ALL DUPLICATED"))
You can check the .length
of each matched letter in string using RegExp
constructor and String.prototype.match()
. If .length
of matched character is 1
return "("
else return ")"
const word = "aleluia";
let res = [...word].map(letter =>
word.match(new RegExp(letter, "ig")).length === 1 ? "(" : ")"
).join("");
console.log(res);
const duplicateEncode = word => {
let newString = ''
word = word.toLowerCase() || word
word.split('').filter((x, index) => {
if(word.indexOf(x) !== index){
newString += ')'
}else if(word.lastIndexOf(x) !== index){
newString += ')'
}else{
newString += '('
}
})
return newString
}
duplicateEncode("O!!!!@k!!!H!!!)!!n!")
There is a more simple way to solve this task. Guess it may be more understandable for newbies in JS because the following solution contains only 4 basic level methods. So here we go.
function duplicateEncode(word) {
return word
.toLowerCase()
.split("")
.map(function (a, i, w) {
return w.indexOf(a) == w.lastIndexOf(a) ? "(" : ")";
})
.join("");
}