Scrabble Scorer Part 2

The context: this is an exercise that was given to me in a coding boot camp. The solution was compiled in a JavaScript file in repl.it and the user interaction was within the terminal.

The Prompt

To remind you: we have been instructed to update the old Scrabble scorer algorithm. We have completed the initialPrompt for the program. Now we have these steps left:

  1. initialPrompt: ask the user which scoring algorithm they wish to use
  2. transformFunction: as the name suggests, transforms the oldPointStructure and returns a newPointStructure
  3. Construct three different scoring algorithms(each will be an object with 3 key/value pairs(not sure how this is going to work/look at this point)
  4. scoringAlgorithmsArray: initialize this array
  5. runProgam: tie it all together

transformFunction

The oldPointStructure object we have been given:

const oldPointStructure = {
   1: ['A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T'],
   2: ['D', 'G'],
   3: ['B', 'C', 'M', 'P'],
   4: ['F', 'H', 'V', 'W', 'Y'],
   5: ['K'],
   8: ['J', 'X'],
   10: ['Q', 'Z']
};

The keys hold the score for the letters that are in the array of that key's value. This is inefficient because the program must iterate through each key and then check within the array of its value. The exercise is suggesting to have 26 keys, one for each letter, and for the keys to be the letters themselves. This eliminates the search within the search process. Well, sure, that makes the program more efficient, but now I'm going to have 26+ lines of code to write for just this piece of the program.

HA! The exercise itself is telling me to cool my jets. Remind me to read the whole prompt before writing these things next time. 🙂

The textbook tells us to:

  1. Write a transform function that takes an object as a parameter. Calling transform(oldPointStructure) will return an object with lowercase letters as keys. The value for each key will be the points assigned to that letter.
  2. Initialize newPointStructure by setting it equal to transform(oldPointStructure).
  3. Hints:
    • Recall that for...in loops iterate over the keys within an object.
    • To access the letter arrays within oldPointStructure, use bracket notation (oldPointStructure['key']).
    • To access a particular element within a letter array, add a second set of brackets (oldPointStructure['key'][index]), or assign the array to a variable and use variableName[index].

Alright, let's take some baby steps through this:

Write the transform function

The basic syntax of this will look like:

let transform = function(oldAndBusted) {
   // .toLowerCase() will need to be used in here somewhere
   // return newHotness
}

Next, I believe they are wanting me to iterate through each letter in the oldPointStructure array to build the newStructureArray. Therefore, I will need a for loop. (In this instance the hints are telling me to use a for...in loop.) Lord knows I don't remember what a for...in function looks like so after some research it seems that: The body of the for...in loop needs to:

  • Construct a new object(what we're calling newHotness)
  • Iterate through each value in each key of the oldPointStructure
  • Reminder: to access the value in the keys we use object['key'][index]
  • Add to the new object a key for every letter with its corresponding score as the value (we achieve this with objectName["new-key"] = propertyValue; )

With these things in mind let's start to build out the rest of the function:

let transform = function(oldAndBusted) {
   newHotness = { };
   for (key in oldAndBusted) {
      ...
      newHotness["letter"] = score;
   }
   // .toLowerCase() will need to be used in here somewhere
   return newHotness;
}

newHotness = { }; - this initializes the empty object we are trying to build So where the ... is I need to iterate through each value in each key of the old object. We just completed a studio that has two for loops so I'm gonna try that out and see what happens. ...

Well, I hit a wall:

let transform = function (oldAndBusted) {
   newHotness = { };
   for (key in oldAndBusted) {
      for (j=0; j<   ;j++) {
      newHotness["letter(value[j] in old object key [i])"] = score(old object key number I);
      }
   // .toLowerCase() will need to be used in here somewhere
   return newHotness;
}

I was looking for ways to iterate through each value in the key, so a second for loop seemed to be the answer, but I wasn't sure how to write the for loop. I was also trying to initialize the keys in the new object, but wasn't sure how to write it out.


After I let this sit in my brain overnight, I was able to tighten this up a bit. I realized that each key was an array and I can access the length of the array with the length method. I then figured out how to initialize the new key in the new object:

let transform = function(oldAndBusted) {
  newHotness = { };
  for (key in oldAndBusted) {
    for(j=0; j<key.length; j++)
    newHotness[([key][j])] = key;
  }
    // .toLowerCase() will need to be used in here somewhere
    return newHotness
}
console.log(transform(oldPointStructure));

Output: { '1': '1', '2': '2', '3': '3', '4': '4', '5': '5', '8': '8', '10': '10', undefined: '10' }

Well, it added keys to the object, but not the way I had hoped...

Let's try again.

let transform = function(oldAndBusted) {
  newHotness = { };
  for (key in oldAndBusted) {
    keyArray = oldAndBusted[key];
    newHotness[keyArray[0]] = key;
    }        
    return newHotness
    // .toLowerCase() will need to be used in here somewhere
}
console.log(transform(oldPointStructure));

Output: { A: '1', D: '2', B: '3', F: '4', K: '5', J: '8', Q: '10' }

Closer! But now I need to have a key for each letter... How can I iterate through the array within each key of the oldPointStructure?

Another for loop!

let transform = function(oldAndBusted) {
  newHotness = { };
  for (key in oldAndBusted) {
    keyArray = oldAndBusted[key];
    for(i=0; i<keyArray.length; i++) {
      newHotness[keyArray[i]] = key;
      }
  }        
  return newHotness
  // .toLowerCase() will need to be used in here somewhere
}
console.log(transform(oldPointStructure));

Output: { A: '1', E: '1', I: '1', O: '1', U: '1', L: '1', N: '1', R: '1', S: '1', T: '1', D: '2', G: '2', B: '3', C: '3', M: '3', P: '3', F: '4', H: '4', V: '4', W: '4', Y: '4', K: '5', J: '8', X: '8', Q: '10', Z: '10' }

I did the thing! Problems:

  • The scores are strings
  • The letters are upper case

One more try:

let transform = function(oldAndBusted) {
  newHotness = { };
  for (key in oldAndBusted) {
    keyArray = oldAndBusted[key];
    for(i=0; i<keyArray.length; i++) {
      newHotness[keyArray[i].toLowerCase()] = Number(key);
      }
  }        
  return newHotness
}
console.log(transform(oldPointStructure));

Output: { a: 1, e: 1, i: 1, o: 1, u: 1, l: 1, n: 1, r: 1, s: 1, t: 1, d: 2, g: 2, b: 3, c: 3, m: 3, p: 3, f: 4, h: 4, v: 4, w: 4, y: 4, k: 5, j: 8, x: 8, q: 10, z: 10 }

Huzzahhhh!!!!!! The only other issue I would see is that the letters are not sorted, but I'll save that for later. I don't think it's necessarily an issue, but the perfectionist in me is agitated by it.

Initialize newPointStructure

Easy peasy!

newPointStructure = transform(oldPointStructure);

On to the next step! What do you think? Did I accomplish the task of creating the transformFucntion the way you would have? What would you have done differently?