0

I have the following array that I'd like to transform into an Object with unique hobbies as the keys

const arr = [
  { name: 'Joe', hobbies: ['skating', 'biking', 'music'] },
  { name: 'Kim', hobbies: ['fishing', 'biking', 'karate'] },
  { name: 'Ben', hobbies: ['surfing'] },
]

I use lodash's handy groupBy function but it groups the multiple array elements into single keys like so

{
  'skating,biking,music': [
    { name: 'Joe' }
  ],
  'fishing,biking,karate': [
    { name: 'Kim' }
  ],
  'surfing': [
    { name: 'Ben' }
  ],
}

What I need is the following output (note the objects are repeated for each of their respective hobbies)

{
  biking: [
    { name: 'Joe' },
    { name: 'Kim' }
  ],
  skating: [
    { name: 'Joe' }
  ],
  karate: [
    { name: 'Kim' }
  ],
  surfing: [
    { name: 'Ben' }
  ],
  ...
}

Is there a simple way to group this array without looping through each array element, splitting them up and regrouping? Would like to avoid this if there's better utility method out there I'm unaware of

0

3 Answers 3

1

You can iterate each item and each hobbie and then add it to a result object:

const arr = [
  { name: 'Joe', hobbies: ['skating', 'biking', 'music'] },
  { name: 'Kim', hobbies: ['fishing', 'biking', 'karate'] },
  { name: 'Ben', hobbies: ['surfing'] }
]

const result = {};
arr.forEach(item => 
  item.hobbies.forEach(hobbie => 
    result[hobbie] = (result[hobbie] || []).concat({name: item.name})
  )
)

console.log(result);

Sign up to request clarification or add additional context in comments.

1 Comment

Brilliant! This works just how I need it to
1

const arr = [
  { name: 'Joe', hobbies: ['skating', 'biking', 'music'] },
  { name: 'Kim', hobbies: ['fishing', 'biking', 'karate'] },
  { name: 'Ben', hobbies: ['surfing'] }
]

const result = {};
arr.forEach(item => 
  item.hobbies.forEach(hobbie => 
    result[hobbie] = result[hobbie]?[...result[hobbie],{name: item.name}]: [{name: item.name}]
  )
)

console.log(result);

Comments

0

I've renamed arr to people for better understanding.

const people = [
  { name: 'Joe', hobbies: ['skating', 'biking', 'music'] },
  { name: 'Kim', hobbies: ['fishing', 'biking', 'karate'] },
  { name: 'Ben', hobbies: ['surfing'] },
];

function transform(people) {
  // get all hobbies and remove duplicates
  const hobbies = [... new Set(
    people.reduce((hobbies, person) => hobbies.concat(person.hobbies),  [])
  )];
  const res = {};
  // take a hobby and use it as key
  for (let hobby of hobbies) {
    res[hobby] = people
      .filter((person) => person.hobbies.includes(hobby))
      .map((person) => { return { name: person.name }; });
  }
  return res;
}

console.log(transform(people));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.