So I found a problem in an article (can't find the link or I'd have the solution) that asked the following question.
Given some user data sort users by skill. The following is the data
const namesAndSkills = {
// Dev : Skills
mark : ["javascript","react","java"],
rob : "javascript",
patrick : ["javascript", "react", "python"]
}
Solution(expected output):
Javascript: ["mark", "rob", "patrick"],
react: ["mark", "patrick"],
java: mark,
python: patrick
My solution has only been able to separate the skills from the users, but I can't seem to find a way to compare the users with the skills.
const data = {
// // Dev : Skills
mark: ["javascript", "react", "java"],
rob: "javascript",
patrick: ["javascript", "react", "python"]
}
function swapNamesAndSkills(object) {
let data = Object.entries(object); //Was thinking of using the separated entries to compare, but couldn't evaluate correctly.
//Create a map to store our end key / values
let skillsToNames = new Map();
let skills = [].concat(...Object.values(object));
for (let i = 0; i < skills.length; i++) {
//if map doesnt have the skill as a key, add skill
if (!skillsToNames.has(skills[i])) {
//array of names that have the skill
skillsToNames.set(skills[i], []);
}
}
console.log(skillsToNames);
}
swapNamesAndSkills(data);
As you see I was looking at ways forward, but can't seem to land a solid way to reverse the data. Solution doesn't have to solve the problem, I'm just stuck and can't find my way to the finish line.
You could reduce through the entries of the object and create a new object. Since value can either be a string or an array, you can use [].concat(value) to get an array of skills to loop through.
Same logic applies while adding a skill as a key to the accumulator. If the skill doesn't exist, just assign acc[skill] = name. If the key already exists, use [].concat(acc[skill], name) because acc[skill] could either be a string or an array.
const namesAndSkills = {
mark: ["javascript", "react", "java"],
rob: "javascript",
patrick: ["javascript", "react", "python"]
}
const output = Object.entries(namesAndSkills).reduce((acc, [name, value]) => {
[].concat(value).forEach(skill => {
if (acc[skill])
acc[skill] = [].concat(acc[skill], name)
else
acc[skill] = name;
})
return acc
}, {})
console.log(output)
You could also use for...in to loop through the keys of namesAndSkills and create the output
const namesAndSkills = {
mark: ["javascript", "react", "java"],
rob: "javascript",
patrick: ["javascript", "react", "python"]
}
const output = {}
for (const name in namesAndSkills) {
for (const skill of [].concat(namesAndSkills[name])) {
if (output[skill])
output[skill] = [].concat(output[skill], name)
else
output[skill] = name;
}
}
console.log(output)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With