0

My question is very trivial but I've got completely lost.

I'm using Reactjs. I've got an array of objects like this:

const modules = [
  {
    thematicArea: "Topic 1",
    id: 1,
    name: "Name 1",
    details: [
      "Lorem ipsum",
      "Lorem ipsum 2"
    ]
  },
  {
    thematicArea: "Topic 2",
    id: 2,
    name: "Name 2",
    details: [
      "Lorem ipsum",
      "Lorem ipsum 2"
    ]
  },
  {
    thematicArea: "Topic 3",
    id: 3,
    name: "Name 3",
    details: [
      "Lorem ipsum",
      "Lorem ipsum 2"
    ]
  },

  {
    thematicArea: "Topic 1",
    id: 4,
    name: "Name 4",
    details: [
      "Lorem ipsum",
      "Lorem ipsum 2"
    ]
  },
{
    thematicArea: "Topic 3",
    id: 5,
    name: "Name 5",
    details: [
      "Lorem ipsum",
      "Lorem ipsum 2"
    ]
  }
]

I want to render it as:

Topic 1:
- Name 1
- Name 4

Topic 2:
- Name 2

Topic 3:
- Name 3
- Name 5

So far I've tried to use LoDash _.groupBy and juggled some mapKeys, mapValues but as I said at the beginning - I've completely lost. Please, help me to find the best solution...

https://codesandbox.io/s/8p21n6p09l -> here is a sandbox where I need to implement the solution. A source object is in App.js and I've tried to use LoDash in components -> thematicArea.jsx Hope it'll help in helping me ; )

4
  • 1
    Can you show what you did with lodash that is not working? Commented Sep 5, 2018 at 12:02
  • At first I did orderedModules = _.groupBy(this.modules, thematicArea => { return thematicArea.thematicArea; }); to get order it like {Topic 1: Array(2), Topic 2: Array(1), Topic 3: Array(2)} I can get thematicArea by Object.getOwnPropertyNames(this.orderedModules) and tried to get names by names = _.mapValues(this.orderedModules, e => _.mapValues(e, f => f.name)) but...it's clearly wrong. Have no good clue how to mix it. Commented Sep 5, 2018 at 12:07
  • Please edit your question with what your tried, the formatting is better. Commented Sep 5, 2018 at 12:13
  • Added sandbox where it can be cleanerr explained. I've tried to implement my solutions in components -> thematicArea.jsx Commented Sep 5, 2018 at 12:23

2 Answers 2

1

First make an Object which's keys are the thematicAreas and which's values are an array of the names, after that just return in the wanted format:

const modules=[{thematicArea:"Topic 1",id:1,name:"Name 1",details:["Lorem ipsum","Lorem ipsum 2"]},{thematicArea:"Topic 2",id:2,name:"Name 2",details:["Lorem ipsum","Lorem ipsum 2"]},{thematicArea:"Topic 3",id:3,name:"Name 3",details:["Lorem ipsum","Lorem ipsum 2"]},{thematicArea:"Topic 1",id:4,name:"Name 4",details:["Lorem ipsum","Lorem ipsum 2"]},{thematicArea:"Topic 3",id:5,name:"Name 5",details:["Lorem ipsum","Lorem ipsum 2"]}]

let themes = {};

modules.forEach(mod => {
  // if there already is an Key named `mod.thematicArea` put the current name in it
  if(themes[mod.thematicArea]) themes[mod.thematicArea].push(mod.name);
  // else create that property and make it an array containing the mod.name
  else themes[mod.thematicArea] = [mod.name];
});

console.log(themes)

/**themes = Object.keys(themes).map(key => {
  return (
    <div>
    <h3>{key}</h3>
    <ul>
    {themes[key].map(name => <li>{name}</li>)}
    </ul>
    </div>
  )
});**/

After that you can render it:

const modules=[{thematicArea:"Topic 1",id:1,name:"Name 1",details:["Lorem ipsum","Lorem ipsum 2"]},{thematicArea:"Topic 2",id:2,name:"Name 2",details:["Lorem ipsum","Lorem ipsum 2"]},{thematicArea:"Topic 3",id:3,name:"Name 3",details:["Lorem ipsum","Lorem ipsum 2"]},{thematicArea:"Topic 1",id:4,name:"Name 4",details:["Lorem ipsum","Lorem ipsum 2"]},{thematicArea:"Topic 3",id:5,name:"Name 5",details:["Lorem ipsum","Lorem ipsum 2"]}]

let themes = {};

modules.forEach(mod => {
  // if there already is an Key named `mod.thematicArea` put the current name in it
  if(themes[mod.thematicArea]) themes[mod.thematicArea].push(mod.name);
  // else create that property and make it an array containing the mod.name
  else themes[mod.thematicArea] = [mod.name];
});

themes = Object.keys(themes).map(key => {
  return (
    <div>
    <h3>{key}</h3>
    <ul>
    {themes[key].map(name => <li>{name}</li>)}
    </ul>
    </div>
  )
});

ReactDOM.render(
  themes,
  document.getElementById('root')
);
<script src="https://unpkg.com/react/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script>
<div id="root"></div>

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

2 Comments

Seriously? Simply as that? Just can believe I couldn't figure it out by myself - I'm a little bit embarassed : P I hope it'll work after implementation to my bigger project ; ) Thanks a lot! You're the best!
No Problem :-) I'm currently learning React, so this was a nice way to apply my knowledge ;-)
0

You could use Array#reduce to do the group-by operation.

const modules = [
  {
    thematicArea: "Topic 1",
    id: 1,
    name: "Name 1",
    details: [
      "Lorem ipsum",
      "Lorem ipsum 2"
    ]
  },
  {
    thematicArea: "Topic 2",
    id: 2,
    name: "Name 2",
    details: [
      "Lorem ipsum",
      "Lorem ipsum 2"
    ]
  },
  {
    thematicArea: "Topic 3",
    id: 3,
    name: "Name 3",
    details: [
      "Lorem ipsum",
      "Lorem ipsum 2"
    ]
  },

  {
    thematicArea: "Topic 1",
    id: 4,
    name: "Name 4",
    details: [
      "Lorem ipsum",
      "Lorem ipsum 2"
    ]
  },
{
    thematicArea: "Topic 3",
    id: 5,
    name: "Name 5",
    details: [
      "Lorem ipsum",
      "Lorem ipsum 2"
    ]
  }
]

const grouped = modules.reduce((groups, module) => {
    if (!groups[module.thematicArea]) {
        groups[module.thematicArea] = [];
    }
    groups[module.thematicArea].push(module.name);
    return groups;
}, {});

console.log(grouped);

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.