0

I've already did this using a loop but our instructor said that it can be done with a shorter and simpler method/function. We are not allowed to use for loops or foreach. We can only use es6 related code.

This is my code.

var total = 0
let givenWord = "cabbage"
let pointsTable = new Map([['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],['y',4],['k',5],['j',8],['x',8],['q',10],['z',10]])

 for(let [...letters] of givenWord){
    for(let [key,value] of pointsTable){
        if(letters == key){
            total = total + value;
            console.log("Total value is " + total)
        }
    }
}  

my problem here is that my loops take up too many lines of code. How do I transform this one into simpler code or using a function/method ? using only ES6?

Michael
  • 1,454
  • 3
  • 19
  • 45
keinz
  • 103
  • 3
  • 15
  • 1
    This is already answered here: https://stackoverflow.com/a/1967132/5605822 – Tasos Mar 04 '20 at 13:56
  • And this is an answer using ES6: https://stackoverflow.com/a/22410812/5605822 – Tasos Mar 04 '20 at 13:57
  • @TasosBu we are not allowed to use foreach or for loops. Only ES6 related answers.. thanks btw! – keinz Mar 04 '20 at 14:02
  • Check my answer @lonewolfkein – Tasos Mar 04 '20 at 14:07
  • 1
    couldn't you just split the string using ```split('')``` and then use the map function to go through each character? – Michael Mar 04 '20 at 14:09
  • 1
    You may want to look up [.reduce()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce), particularly how to accumulate a total over a list. – chazsolo Mar 04 '20 at 14:13

4 Answers4

2

Ok, I created a sort ES6 way to return the chars in an array and run a check function on them:

const pointsTable = new Map([['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],['y',4],['k',5],['j',8],['x',8],['q',10],['z',10]])
// With ES6
const text= 'abcdefg';
const result = [...text].reduce((acc, cur) => {
  return acc + pointsTable.get(cur)
}, 0);
console.log(result);

An other way you could do this is write a while loop and use the String.split(), String.slice() or String.substring() methods to reduce the string to the chars

Tasos
  • 1,880
  • 13
  • 19
  • uhm im still a beginner on this one, how can I compare each character of the array to my mapped letters with scores? Wouldn't it take too much lines of codes if I manually put if ( c == 'a') up to letter z , etc ? – keinz Mar 04 '20 at 14:16
  • I updated the code @lonewolfkein to work with your Map – Tasos Mar 04 '20 at 14:29
  • 1
    this is the code that my instructor was reffering to. the reduce one, you got it right and also simple code and easy to understand! thank you !! – keinz Mar 04 '20 at 14:40
  • 1
    if you dont mind me asking... const result = [...text].reduce((acc, cur) => { return acc + pointsTable.get(cur) }, 0); why did you put }, 0); at the end? and in return what will be the value of acc? All your help is appreciated. Thanks! – keinz Mar 04 '20 at 14:48
  • 1
    it's used to indicate what to start the accumulator at. So in this case you want it to be zero because you are taking a sum of all the values. Say if that value was 10, then the result would be 10+ your result. – Michael Mar 04 '20 at 14:55
1

You can use recursion for this task:

var total = 0
let givenWord = "cabbage"
let pointsTable = new Map([['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],['y',4],['k',5],['j',8],['x',8],['q',10],['z',10]])

const countTotal = (arr, map, points = 0) => {
  if(arr.length === 0) return points
  points += map.get(arr.splice(0,1)[0]) 
  return countTotal(arr, map, points)  
}

console.log(countTotal([...givenWord],pointsTable))
cccn
  • 929
  • 1
  • 8
  • 20
  • thank you! it worked as well but as a beginner its kinda hard to read and understand. But ill study this logic as well and the syntax. Much appreciated. – keinz Mar 04 '20 at 14:36
1

Using the split method it will separate the text into the individual letters. Then you can use the map method to iterate through each of those letters and do a check within that.

const test = 'abcdefg'
let total = 0;
let pointsTable = new Map([['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], 
['y',4],['k',5],['j',8],['x',8],['q',10],['z',10]])

test.split('').map(function(letter){
  let value = pointsTable.get(letter)
  total += value;
});
Michael
  • 1,454
  • 3
  • 19
  • 45
  • thank you for the simplicity of the code. I will study this and the reduce() functtion too:) – keinz Mar 04 '20 at 14:34
1

Here's the shortest way I can think of :

var total = 0
let givenWord = "cabbage"
let pointsTable = new Map([['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],['y',4],['k',5],['j',8],['x',8],['q',10],['z',10]])

let total = givenWord.split``.reduce((a,l)=>a+pointsTable.get(l),0)
console.log("Total value is " + total)

details :

let total =                              // assign to total
    givenWord                            // the givenword
        .split``                         // splited to get an array of characters

        .reduce(                         // call reduce on the array
             (a, l) => {                 // first arg of reduce is a function 
                                         // called for each elements of the array
                                         // arguments are the accumulator, the letter
                  a + pointsTable.get(l) // add the letter score to the accumulator
             },
             0                           // set default value of accumulator (2nd arg of reduce)
         )

fn`` documentation (look at section tagged template),

reduce documentation

jonatjano
  • 3,576
  • 1
  • 15
  • 20