4

What is the most efficient way to replace text like :) -> .

So, assume I have a text like "Hello :) my name is Alex". I should convert the text into "Hello my name is Alex"

I solved this issue with help of lodash utility library.

const replaceStringWithEmoji = (string) => {
  const emojiMap = {
    ':)': '',
    ':(': '',
    ':D': '',
    ';(': '',
    ':O': '',
    ';)': '',
    '8)': '',
    '>:@': '',
  };

  const emojis = [...Object.keys(emojiMap)];
  return _.join(_.map(_.split(string, ' '), (s) => {
    if (_.includes(emojis, s)) {
      return emojiMap[s];
    }
    return s;
  }), ' ');
};

There has to be a better way of doing it. Maybe with Regex?

Short return

 return _.join(_.map(_.split(string, ' '), s => _.includes(emojis, s) ? emojiMap[s] : s), ' '); 
Alex
  • 1,210
  • 3
  • 21
  • 34
  • 4
    If your code works well and there is no issue, please consider posting the question at [codereview.se]. – Wiktor Stribiżew Sep 18 '19 at 07:32
  • 1
    Seems like you need to hardset the majority of this data. Not sure what much more you would like to get this to perform better. :) – Chris Ngo Sep 18 '19 at 07:35
  • 2
    This question is quite open ended. What does 'efficient' and 'better' mean in your situation? If your code is readable and works for all required test cases then do not fall into a trap of doing pre-mature optimisation. – ethane Sep 18 '19 at 07:36

2 Answers2

6

I'd construct a pattern by taking the keys, escaping all the special characters, and joining by |. Then replace by looking up the matched string on the object:

const escape = s => s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');

const replaceStringWithEmoji = (string) => {
  const emojiMap = {
    ':)': '',
    ':(': '',
    ':D': '',
    ';(': '',
    ':O': '',
    ';)': '',
    '8)': '',
    '>:@': '',
  };
  const pattern = new RegExp(
    Object.keys(emojiMap).map(escape).join('|'),
    'g'
  );
  return string.replace(pattern, match => emojiMap[match]);
};

console.log(replaceStringWithEmoji('foo :) bar'));
console.log(replaceStringWithEmoji('foo :) bar 8) baz'));
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
4

You don't need to change your emojiMap to array you can build a regex with alternation and use repalce

const replaceStringWithEmoji = (string) => {
  const emojiMap = {
    ':)': '',
    ':(': '',
    ':D': '',
    ';(': '',
    ':O': '',
    ';)': '',
    '8)': '',
    '>:@': '',
  };
  let regex = /(?::\)|:\(|:D|;\(|:O'|;\)|8\)|>:@)/g
  return string.replace(regex,(m)=>emojiMap[m] || m)
};

console.log(replaceStringWithEmoji("Hello :) my name is Alex"))
Code Maniac
  • 37,143
  • 5
  • 39
  • 60