Anthony
Anthony

Reputation: 87

How to check if a certain character exist more that once in a string?

Javascript newbie here :)

    var word = "Testing";

    function duplicateEncode(word){

      // code goes here...  
    }

    duplicateEncode(word)

How to check if a certain character exist more that once in a string?

say for instance, for the string "Testing", i wanted to have a function that checks if each letter in the said string exist more than once or just once.

I tried playing around with for loops in combination with If else statement but i cant find the solution :( . Also tried .match() method but still to no avail.

var word = "Testing";


function duplicateEncode(word){

  for (i=0; i<word.length; i++){

    var output = "";
    var outputMarcher = word.match(/(word[0]/g);

    console.log(outputMarcher);

  }

}

duplicateEncode(word)

The function should check each character, if the character exist only once then it should console.log "1". otherwise it should console.log "x"

example :

"din" => "111"

"recede" => "1x1x1x"

Upvotes: 2

Views: 2050

Answers (3)

Robby Cornelissen
Robby Cornelissen

Reputation: 97120

Since your original attempt seems to be based on regular expressions, here's one way to do it using a regular expression:

const encode = (word) => word.replace(/(.)(?:(?=.*\1)|(?<=\1.+))|./g, (_, m) => m ? 'x' : '1');

console.log(encode('din'));
console.log(encode('recede'));

This makes use of lookahead and lookbehind assertions, and the replacer function that can be passed to String.prototype.replace().


Note: I just wrote this up in the name of science, so some serious disclaimers:

  1. Lookbehind assertions are not yet supported in all browsers.
  2. Looking at the regex too long will make your eyes bleed.
  3. Who knows? There might be some weird edge cases for which this might not work.

Upvotes: 0

Robby Cornelissen
Robby Cornelissen

Reputation: 97120

You could map the characters in the word to x and 1 depending on whether the same character exists in another position:

const encode = (word) => [...word].map((c1, i1, a) => a.some((c2, i2) => c1 == c2 && i1 != i2) ? 'x' : '1').join('');

console.log(encode('din'));
console.log(encode('recede'));


Here's a detailed breakdown:
Note: if you're not familiar with arrow function syntax, you might want to look into that first.

Step 1: converting the word to a character array

We use the spread syntax to convert the word string into an array of characters. Calling ...word splits up the string into individual characters, and surrounding that with [] consequently captures the result of that operation in an array.
For example, the result of evaluating [...'recede'] is ['r', 'e', 'c', 'e', 'd', 'e'].

Step 2: mapping every character to 1 or x

Now, we try to map each character in that array to a 1 or x character, depending on whether the character also exists in another location in the array. For this we use the Array.prototype.map() function. This function will take every character in the array, run it through a callback function, and capture the result in a new array.

This is the callback function we pass to map():

(c1, i1, a) => a.some((c2, i2) => c1 == c2 && i1 != i2 ) ? 'x' : '1'

This callback function takes three arguments, here named c1, i1 and a:

  • c1 is the character we're currently processing.
  • i1 is the index of that character in the array.
  • a is a reference to the array itself, i.e. the array we obtained in step 1.

In the body of the callback function, we will determine whether 1 or x needs to be returned for the given character. To do this, we use the Array.prototype.some() function. This function will loop over every element in the array and it will return true if it finds at least one element for which a given condition is satisfied; otherwise it will return false. This condition is again expressed as a callback function.

This is the callback function we pass to some():

 (c2, i2) => c1 == c2 && i1 != i2

This callback function takes two arguments, here named c2 and i2:

  • c2 is the character we're currently processing.
  • i2 is the index of that character in the array.

It's important to note that this callback for some() is executed in the scope of the callback for map(). In a more traditional procedural programming style, this would be expressed as a nested loop.

As for the body of this second callback function, we evaluate (c2, i2) => c1 == c2 && i1 != i2, that is to say: we check whether this second character is the same as the first character, but their indexes are different. Or, to put it differently, whether two identical characters exist in different positions in the array.

So, for every character, the call to some() will yield either true or false, depending on whether the character is a duplicate or not. We will then feed that result into a ternary operator to output either 1 or x. In doing so, the character array ['r', 'e', 'c', 'e', 'd', 'e'] will map to the new character array ['1', 'x', '1', 'x', '1', 'x'].

Step 3: putting it all back together

At the very end, we take the result we obtained in step 2, and feed it to the Array.prototype.join() function which will simply concatenate all the characters back together and return a string. This will convert ['1', 'x', '1', 'x', '1', 'x'] into '1x1x1x', which is the required output.

Upvotes: 4

juancarlos
juancarlos

Reputation: 631

you can iterate the string and store key with default value as 1, and check if the object has already a key called as current character and sum 1 more,...


function count(word){
    let letters = {}
    for(let chr of word) {
        letters[chr] = letters.hasOwnProperty(chr) ? letters[chr] + 1: 1;
    }

    return letters;
}

Upvotes: 1

Related Questions