arty
arty

Reputation: 669

Using values from dictionary to code a string

I am trying to write a function -encode(text, keyText)- that takes a string, generally a word and encodes it by changing every letter of the text with that letter's place in the keyText.

If a letter occurs multiple times in the keyText, then it should use every occurrence in encoding process in the same order they occur in the keyText. If it occurs more times in the text, than it loops back to the first, so the first letter is replaced by that letter's place in the keyText, and the second occurrence of that letter is replaced by the second place in the keyText, if the letter comes a third time in the text but only occurred in the keyText twice, than it is replaced by the first place again and so on.

I also wrote a function, getKeys, that takes a string and returns a "dictionary" that gives the places in that sentence for each letter.

Let's say keyText is "And not just the men, but the women and the children, too"

getKeys(keyText) would return : {"A":[1, 29], "N":[2, 4], "D":[3], "O":[5, 25, 44 ,45] ...}

so encode("anna", keyText) should return this:

[1, 2, 4, 29]

function encode(text, keyText) {
        text = text.toUpperCase();
        var key = getKeys(keyText);
        var list = [];
        var counter = 1;

        for(let char of text){
            var len = key[char].length;

            if(counter > len){
                counter = 0;
            }
                list.push(key[char][counter])
                counter++;
            }
        }return list;

The obvious problem with my code is that counter is incremented for all the letters, and not just when it needs to get the second or third value. But if i put the counter in the for loop, than it's not going to work either. I couldn't find a way to tie counter to each character of Text so that it is only incremented if that character has come up more than once.

Upvotes: 0

Views: 38

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370729

Once getKeys is called, and you have an object, you need separate counters for each property in the object. You could use the keys object to construct another one with the same keys, but whose values are indicies indicating the current counter for that key. On each character iteration, look up the associated counter for the character, save the value to return, and increment the counter:

function encode(text, keyText) {
  // var key = getKeys(keyText);
  const keysObj = {"A":[1, 29], "N":[2, 4], "D":[3], "O":[5, 25, 44 ,45] };
  const counters = Object.fromEntries(
    Object.keys(keysObj).map(key => [key, 0])
  );
  return [...text.toUpperCase()]
    .map((char) => {
      const thisCharNumArr = keysObj[char];
      const num = thisCharNumArr[counters[char]];
      counters[char] = (counters[char] + 1) % thisCharNumArr.length;
      return num;
    })
}

console.log(encode('anna'));
console.log(encode('annannnnn'));

Upvotes: 1

Related Questions