Reputation: 45
Return an object where each key is an instructor name and each value is an array of the modules they can teach based on their skills.
Here are the datasets I am supposed to manipulate through:
const instructors = [
{ name: 'Pam', module: 2, teaches: ['scope', 'recursion', 'node'] },
{ name: 'Brittany', module: 2, teaches: ['oop', 'pwas'] },
{ name: 'Nathaniel', module: 2, teaches: ['oop', 'scope', 'mobile'] },
{ name: 'Robbie', module: 4, teaches: ['node', 'pwas'] },
{ name: 'Leta', module: 4, teaches: ['pwas', 'node', 'recursion'] },
{ name: 'Travis', module: 1, teaches: ['javascript', 'html', 'css'] },
{ name: 'Louisa', module: 1, teaches: ['javascript', 'html', 'css', 'node', 'pwas'] },
{ name: 'Christie', module: 3, teaches: ['javascript', 'react', 'node'] },
{ name: 'Will', module: 3, teaches: ['javascript', 'redux', 'react', 'oop', 'scope'] }
];
const cohorts = [
{ cohort: 1806, module: 1, studentCount: 30, curriculum: ['html', 'css', 'javascript'] },
{ cohort: 1804, module: 2, studentCount: 21, curriculum: ['javascript', 'css', 'recursion', 'scope', 'oop'] },
{ cohort: 1803, module: 3, studentCount: 20, curriculum: ['react', 'redux', 'html', 'javascript'] },
{ cohort: 1801, module: 4, studentCount: 18, curriculum: ['pwas', 'mobile', 'node', 'javascript', 'css'] }
];
Below is the code I have tried, I keep having issues iterating through two data sets, linking them together is tough!
This is what I've tried but cannot get the correct arrays to appear as values in the object:
let result1 = instructors.reduce((teacherObj, teacherName) => {
if(!teacherObj[teacherName.name]) {
teacherObj[teacherName.name] = []
// console.log(instructors.map(a => a.module))
}
return teacherObj
}, {})
console.log(result1)
Expected Result:
{
Pam: [2, 4],
Brittany: [2, 4],
Nathaniel: [2, 4],
Robbie: [4],
Leta: [2, 4],
Travis: [1, 2, 3, 4],
Louisa: [1, 2, 3, 4],
Christie: [1, 2, 3, 4],
Will: [1, 2, 3, 4]
}
Upvotes: 3
Views: 44
Reputation: 21130
After working out the answer for myself the result is basically the same as the answer of CertainPerformance.
I opted to use Set as the value in the lookup hash, to directly eliminate duplicates when they are added. My version also uses another technique for flattening the array. I concat
the array using reduce
, instead of spreading the array into a concat
call.
const instructors = [{name: 'Pam', module: 2, teaches: ['scope', 'recursion', 'node']}, {name: 'Brittany', module: 2, teaches: ['oop', 'pwas']}, {name: 'Nathaniel', module: 2, teaches: ['oop', 'scope', 'mobile']}, {name: 'Robbie', module: 4, teaches: ['node', 'pwas']}, {name: 'Leta', module: 4, teaches: ['pwas', 'node', 'recursion']}, {name: 'Travis', module: 1, teaches: ['javascript', 'html', 'css']}, {name: 'Louisa', module: 1, teaches: ['javascript', 'html', 'css', 'node', 'pwas']}, {name: 'Christie', module: 3, teaches: ['javascript', 'react', 'node']}, {name: 'Will', module: 3, teaches: ['javascript', 'redux', 'react', 'oop', 'scope']}];
const cohorts = [{cohort: 1806, module: 1, studentCount: 30, curriculum: ['html', 'css', 'javascript']}, {cohort: 1804, module: 2, studentCount: 21, curriculum: ['javascript', 'css', 'recursion', 'scope', 'oop']}, {cohort: 1803, module: 3, studentCount: 20, curriculum: ['react', 'redux', 'html', 'javascript']}, {cohort: 1801, module: 4, studentCount: 18, curriculum: ['pwas', 'mobile', 'node', 'javascript', 'css']}];
// prepare module lookup hash
let moduleLookup = {};
cohorts.forEach(({module, curriculum}) => {
curriculum.forEach(craft => {
let modules = moduleLookup[craft] || (moduleLookup[craft] = new Set());
modules.add(module);
});
});
// answer
let result = {};
instructors.forEach(({name, teaches}) => {
let modules = teaches
.map(craft => Array.from(moduleLookup[craft])) // get modules for each craft
.reduce((acc, arr) => acc.concat(arr), []); // flatten 1 level
result[name] = Array.from(new Set(modules)); // remove duplicates
});
console.log(result);
Upvotes: 0
Reputation: 370809
First transform the cohorts
array into an object indexed by curriculum, whose values are that curriculum's associated module(s), allowing for quick lookup. That is, an object like:
// modulesByCurriculum
{
"html": [ // html is present in module 1 and 3
1,
3
],
"css": [ // css is present in modules 1, 2, and 4
1,
2,
4
], ...
This allows you to take a program name, like scope
, and get its associated modules quickly.
Then, iterate through the instructors and look up each associated curriculum to find the modules, deduplicating via a Set:
const instructors = [
{ name: 'Pam', module: 2, teaches: ['scope', 'recursion', 'node'] },
{ name: 'Brittany', module: 2, teaches: ['oop', 'pwas'] },
{ name: 'Nathaniel', module: 2, teaches: ['oop', 'scope', 'mobile'] },
{ name: 'Robbie', module: 4, teaches: ['node', 'pwas'] },
{ name: 'Leta', module: 4, teaches: ['pwas', 'node', 'recursion'] },
{ name: 'Travis', module: 1, teaches: ['javascript', 'html', 'css'] },
{ name: 'Louisa', module: 1, teaches: ['javascript', 'html', 'css', 'node', 'pwas'] },
{ name: 'Christie', module: 3, teaches: ['javascript', 'react', 'node'] },
{ name: 'Will', module: 3, teaches: ['javascript', 'redux', 'react', 'oop', 'scope'] }
];
const cohorts = [
{ cohort: 1806, module: 1, studentCount: 30, curriculum: ['html', 'css', 'javascript'] },
{ cohort: 1804, module: 2, studentCount: 21, curriculum: ['javascript', 'css', 'recursion', 'scope', 'oop'] },
{ cohort: 1803, module: 3, studentCount: 20, curriculum: ['react', 'redux', 'html', 'javascript'] },
{ cohort: 1801, module: 4, studentCount: 18, curriculum: ['pwas', 'mobile', 'node', 'javascript', 'css'] }
];
const modulesByCurriculum = cohorts.reduce((a, { module, curriculum }) => {
curriculum.forEach((currName) => {
if (!a[currName]) {
a[currName] = [];
}
a[currName].push(module);
});
return a;
}, {});
const output = instructors.reduce((a, { name, teaches }) => {
a[name] = [...new Set(
teaches.flatMap(currName => modulesByCurriculum[currName])
)];
return a;
}, {});
console.log(output);
If you can't use flatMap
, you can spread into concat
instead:
const instructors = [
{ name: 'Pam', module: 2, teaches: ['scope', 'recursion', 'node'] },
{ name: 'Brittany', module: 2, teaches: ['oop', 'pwas'] },
{ name: 'Nathaniel', module: 2, teaches: ['oop', 'scope', 'mobile'] },
{ name: 'Robbie', module: 4, teaches: ['node', 'pwas'] },
{ name: 'Leta', module: 4, teaches: ['pwas', 'node', 'recursion'] },
{ name: 'Travis', module: 1, teaches: ['javascript', 'html', 'css'] },
{ name: 'Louisa', module: 1, teaches: ['javascript', 'html', 'css', 'node', 'pwas'] },
{ name: 'Christie', module: 3, teaches: ['javascript', 'react', 'node'] },
{ name: 'Will', module: 3, teaches: ['javascript', 'redux', 'react', 'oop', 'scope'] }
];
const cohorts = [
{ cohort: 1806, module: 1, studentCount: 30, curriculum: ['html', 'css', 'javascript'] },
{ cohort: 1804, module: 2, studentCount: 21, curriculum: ['javascript', 'css', 'recursion', 'scope', 'oop'] },
{ cohort: 1803, module: 3, studentCount: 20, curriculum: ['react', 'redux', 'html', 'javascript'] },
{ cohort: 1801, module: 4, studentCount: 18, curriculum: ['pwas', 'mobile', 'node', 'javascript', 'css'] }
];
const modulesByCurriculum = cohorts.reduce((a, { module, curriculum }) => {
curriculum.forEach((currName) => {
if (!a[currName]) {
a[currName] = [];
}
a[currName].push(module);
});
return a;
}, {});
const output = instructors.reduce((a, { name, teaches }) => {
a[name] = [...new Set(
[].concat(...teaches.map(currName => modulesByCurriculum[currName]))
)];
return a;
}, {});
console.log(output);
Upvotes: 2