1

In my React program, suppose I had the following dictionary / object

const myDict = {
    "a":"Value 1",
    "b":"Value 2",
    "hello":"Value 3",
    "Bye":"Value 4"
}

(note that no keys have values existing in any other keys - For example, no key can contain the a letter since that is a different key)

And I will be receiving a string that will ONLY CONSIST OF PERMUTATIONS OF THE KEYS TO THIS OBJECT, so, for example, possible string entries will be:

  • "abhellob"
  • "ababByeahello"
  • "ByehelloByeba"
  • etc.

And I am looking to create a function that will break the input string down into its constituent parts based upon the keys of myDict.

So, for example,

  • "abhellob" would become ["a", "b", "hello", "b"]

How can I create such a function? I've tried, but am getting lost with having to deal with different length keys to myDict and I don't know how to do it.

John Bustos
  • 19,036
  • 17
  • 89
  • 151

2 Answers2

4

A regular expression that alternates between the different keys would do the trick.

const myDict = {
    "a":"Value 1",
    "b":"Value 2",
    "hello":"Value 3",
    "Bye":"Value 4"
}
const pattern = new RegExp(
  Object.keys(myDict).join('|'),
  'g'
);
console.log("abhellob".match(pattern));
console.log("ababByeahello".match(pattern));
console.log("ByehelloByeba".match(pattern));

(If some keys could have character overlap, a start would be to sort the keys so the longest ones come first.)

const myDict = {
    "a":"Value 1",
    "b":"Value 2",
    "hello":"Value 3",
    "Bye":"Value 4"
}
const pattern = new RegExp(
  Object.keys(myDict)
    .sort((a, b) => a.length - b.length)
    .join('|'),
  'g'
);
console.log("abhellob".match(pattern));
console.log("ababByeahello".match(pattern));
console.log("ByehelloByeba".match(pattern));
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • The sort is a nice touch but according to the question it's not necessary since no key can contain another key. Might be worth adding a comment next to it just to clarify. Upvoted Regardless – nick zoum Apr 19 '22 at 01:06
  • @nickzoum Oh, you're right, I saw the `a` and `b` keys and was worried about them possibly appearing in other keys, but capital letters are different from lowercase. – CertainPerformance Apr 19 '22 at 01:07
  • 1
    FYI due to this being Regex, this breaks when the dict keys contain Regex expressions. For example: `"[":"Value 1",`. Dynamically generating Regex queries off of user input is generally unwise. – Slava Knyazev Apr 19 '22 at 01:13
  • 1
    @SlavaKnyazev Can be fixed with https://stackoverflow.com/a/3561711, but doesn't look necessary here – CertainPerformance Apr 19 '22 at 01:14
3

You can do this without Regex:

function getFragments(entryString){
  const myDict = {
"a":"Value 1",
"b":"Value 2",
"hello":"Value 3",
"Bye":"Value 4"
  }
  const keys = Object.keys(myDict);
  
  const result = [];
  let remainingString = entryString;
  while (remainingString) {
const nextWord = keys.find(key => remainingString.startsWith(key));
if (!nextWord) throw new Error("Couldn't match with word");

result.push(nextWord);
remainingString = remainingString.slice(nextWord.length);
  }
  
  return result;
}

console.log(getFragments("abhellob"));
console.log(getFragments("ababByeahello"));
console.log(getFragments("ByehelloByeba"));
Slava Knyazev
  • 5,377
  • 1
  • 22
  • 43