'JavaScript: Create function that returns an object whose keys match the elements in the array of values using callbacks

My objective is as follows:

Construct a function multiMap that will accept two arrays - an array of values and an array of callbacks. multiMap will return an object whose keys match the elements in the array of values. The corresponding values that are assigned to the keys will be arrays consisting of outputs from the array of callbacks, where the input to each callback is the key.

I tried the code below:

const multiMap = (arrOne, arrTwo) => {

  let newObj = {}; 

  for (let i=0; i<arrOne.length; i++){
    let element = arrOne[i]; 

    console.log(i)

    newObj[element] = arrTwo[i](element); 
  }
  return newObj; 
}



// Uncomment these to check your work!
function uppercaser(str) { return str.toUpperCase(); }
function capitalize(str) { return str[0].toUpperCase() + str.slice(1).toLowerCase(); }
function repeater(str) { return str + str; }

// arrOne
const items = ['catfood', 'glue', 'beer'];
// arrTwo
const functions = [uppercaser, capitalize, repeater];


console.log(multiMap(items, functions));

My code returns: { catfood: 'CATFOOD', glue: 'Glue', beer: 'beerbeer' }

I want it to return: { catfood: ['CATFOOD', 'Catfood', 'catfoodcatfood'], glue: ['GLUE', 'Glue', 'glueglue'], beer: ['BEER', 'Beer', 'beerbeer'] }, 'Beer', 'beerbeer'] }

What am I doing wrong?

Note: I know I can use modifying functions (i.e. reduce) to do this but I want to figure it out first using for loop.



Solution 1:[1]

You have to iterate over the function array in order to create an the associated array of results.

const multiMap = (arrOne, arrTwo) => {

  let newObj = {}; 

  for (let i=0; i<arrOne.length; i++){
    let element = arrOne[i]; 

    console.log(i)

    var arr = [];
    for (let f=0;f<functions.length;f++) {
      arr.push(functions[f](element));
    }

    newObj[element] = arr; 
  }
  return newObj; 
}



// Uncomment these to check your work!
function uppercaser(str) { return str.toUpperCase(); }
function capitalize(str) { return str[0].toUpperCase() + str.slice(1).toLowerCase(); }
function repeater(str) { return str + str; }

// arrOne
const items = ['catfood', 'glue', 'beer'];
// arrTwo
const functions = [uppercaser, capitalize, repeater];


console.log(multiMap(items, functions));

Solution 2:[2]

A more functional solution would be,

const multiMap = (arrVals, arrCallbacks) => arrVals.reduce((acc, curr) => {
  acc[curr] = arrCallbacks.map(cb => cb(curr));
  return acc;
}, {});

console.log(multiMap(['catfood', 'glue', 'beer'], [(str) => str.toUpperCase(), (str) => str[0].toUpperCase() + str.slice(1).toLowerCase(), (str) => str + str]));
// should log: { catfood: ['CATFOOD', 'Catfood', 'catfoodcatfood'], glue: ['GLUE', 'Glue', 'glueglue'], beer: ['BEER', 'Beer', 'beerbeer'] }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 nixkuroi
Solution 2 Ashutosh Bhadoria