DEV Community 👩‍💻👨‍💻

Cover image for React.js - Interview Question - duplicate hashtag remover.
Rajesh Royal
Rajesh Royal

Posted on

React.js - Interview Question - duplicate hashtag remover.

Had an Interview for React.js frontend developer for one of the MNC company. The question they asked was to build a Duplicate Hashtag remover

Question Statement:

There has to be an textarea in which user can input as many hashtags as he wants, the tags will be separated by a space and starts with # symbol.

Now the task is to find the duplicate hashtags entered by user and and show the listing below the textarea input. In the listing there has to be a X delete button by clicking on it it will remove the duplicate from the textarea as well as from the listing of duplicates.

Sample Input:

#kashmir #kashmirvalley #srinagar #dallake #reels #trendingreels #reelitfeelit #viral #viralvideos #viralvideos #viralreels #feelkaroreelkaro #mountains #love #couplegoals #bucketlist #moretocome #2022   #srinagar #dallake #reels #trendingreels #srinagar #dallake #reels #trendingreels #srinagar #dallake #reels #trendingreels #love #bucketlist
Enter fullscreen mode Exit fullscreen mode

Sample Output:

#kashmir #kashmirvalley #srinagar #dallake #reels #trendingreels #reelitfeelit #viral #viralvideos #viralreels #feelkaroreelkaro #mountains #love #couplegoals #bucketlist #moretocome #2022 #bucketlistour
Enter fullscreen mode Exit fullscreen mode

Solution CodeSandbox link - Duplicate Hashtags Remover

Time Duration - 1hr.
Interviewer was very nice and was helped when I was stuck at updating the state particularly.

Thank you for reading. Let me know if this is helpful and you can also share your questions in the comment box. (only the live coding or assignment questions.)

Top comments (9)

Collapse
rhobert72 profile image
Roberto Garella

Find duplicates and remove them using RegExp.

Sorry, but I did just two functions... 😇

const text = `#t1 #t2
#t3 #t4 #t2 #t5 #t3
#t2`;

const getDupTags = txt => {
    const matches = txt.match(/\B#\S+\b/gm) ?? [];
    return [...new Set(matches.filter((tag, index) => matches.indexOf(tag) !== index))]
}


console.log(getDupTags(text))

const removeDupTags = (str, txt) => {
    let isFirstMatch = true;
    let matches;
    const regexp = new RegExp(str, 'dgm')
    while((matches = regexp.exec(txt))){
        if(isFirstMatch){
            isFirstMatch = false;
        }else if(matches){
        const [startIndex, endIndex] = matches.indices.flat();
        txt = txt.substring(0, startIndex - 1)+ txt.substring(endIndex)
        }
    }
    return txt;
}
console.log(removeDupTags('#t2', text))

Enter fullscreen mode Exit fullscreen mode
Collapse
rajeshroyal profile image
Rajesh Royal Author

@rhobert72 nice solution, also can you please write a little bit about the regex expression you used to understand it better. Like what this line is doing txt.match(/\B#\S+\b/gm)

Thanks.

Collapse
rhobert72 profile image
Roberto Garella

To find a tag within a text we have to play with word boundaries.
With \B (b upper case) we are looking for a position is not preceded and not followed by a word character. In our case we are looking for a word starts with # precede by a white space.
Instead, with \b (notice b is lower case) we are looking for a position preceded by a word character but not followed by a word character.
With \S+ we are looking for all characters (one or more than one) excluded: new line, tab and so on.
Flags: g stands for global and tells to regexp engine don't stop at the first match; m stands for multiline.
Flag m is not necessary. 😁

Thread Thread
rajeshroyal profile image
Rajesh Royal Author

Thanks @rhobert72 ✌🏻

Collapse
uicoder511 profile image
Umang • Edited on

My solution:
codesandbox.io/s/duplicate-hashtag...

+ Real-time duplicate checker
+ Works fine if string has additonal spaces
- Did not check if tags start with # ( duplicate words remover )

Collapse
samselfridge profile image
samselfridge • Edited on

You're calling set state for every new duplicate item, maybe react will batch this and save you, but don't count on it. You're better off initalizing a new array, pushing duplicates on to it then calling setState 1 time at the end.

  const findDuplicateTags = () => {
    let tagsMap = new Map();
    const duplicates = [];
    hashtags.split(" ").forEach((tag) => {
      tag = tag.trim();
      if (tag) {
        if (tagsMap.has(tag)) {
          duplicates.push(tag);
        } else {
          tagsMap.set(tag, 0);
        }
      }
    });
    setDuplicates(duplicates);
  };
Enter fullscreen mode Exit fullscreen mode

Other things to note:

  • This doesn't check for # as a tag so it would delete duplicate words
  • Doesn't handle additional whitespace, look at String.trim()

Nice use of Map. Not bad for a interview but that repeated setState will absolutely destroy your apps performance and due to the async nature of setState could even get you into unpredictable behavior.

Collapse
rajeshroyal profile image
Rajesh Royal Author

hehe true I should have used this method. But there were many factors - and the biggest one was time bounding and it makes person nervous. I will be keeping it in mind.
Thank you.

Collapse
capscode profile image
capscode • Edited on

If you just want to remove the duplicates, then Set will be the easier solution to this

[...new Set(str.split(' '))] //str is the string holding all the hash tags entered
Enter fullscreen mode Exit fullscreen mode

this is just the snippet and not the complete implementation

Collapse
rajeshroyal profile image
Rajesh Royal Author

The duplicates needs to be removed one by one not at once.

🌚 Life is too short to browse without dark mode