javascriptarraystypescriptpure-js

Group array data by name


I'm trying to develop an array with expertise 'Transport' containing each sector and the text assigned to them.

This is what I have:


    - Healthcare
    -- Data-driven insights to improve healthcare
    -- Novel data mining and visualisation
    -- Human-centred augmented and virtual realities

    - Energy
    -- Urban Analytics
    -- Understanding patterns of consumer behaviour
    -- Optimising energy systems

This is what I'm trying to do:


    - expertise (e.g Transport)

    -- sector (e.g Data)
    --- text (e.g Urban Analytics)
    --- text (e.g Understanding patterns of consumer behaviour)
    --- text (e.g Human-centred augmented and virtual realities)

    -- sector (e.g Engineering)
    --- text (e.g Optimising energy systems)
    --- text (e.g High speed rail and system integration innovation)
    --- text (e.g Human-centred robotic and autonomous systems)
    --- text (e.g Surface engineering across the length scales)

    -- sector (e.g Environment)
    --- text (e.g Europe’s leading city simulation capability)

    - expertise
    -- sector
    --- text

Here's the code I'm using at the moment if anyone is able to help I would highly appreciate it.

var items = [{
    "item": {
      "id": 0,
      "sector": 'Data',
      "expertise": ["Healthcare"],
      "text": "Data-driven insights to improve healthcare"
    }
  },
  {
    "item": {
      "id": 1,
      "sector": 'Data',
      "expertise": ["Energy", "Transport", "Cities"],
      "text": "Urban Analytics"
    }
  },
  {
    "item": {
      "id": 2,
      "sector": 'Data',
      "expertise": ["Energy", "Transport", "Consumer"],
      "text": "Understanding patterns of consumer behaviour"
    }
  },
  {
    "item": {
      "id": 3,
      "sector": 'Data',
      "expertise": ["Healthcare", "Consumer"],
      "text": "Novel data mining and visualisation"
    }
  },
  {
    "item": {
      "id": 4,
      "sector": 'Data',
      "expertise": ["Healthcare", "Transport", "Consumer"],
      "text": "Human-centred augmented and virtual realities"
    }
  },
  {
    "item": {
      "id": 5,
      "sector": 'Healthcare',
      "expertise": ["Healthcare"],
      "text": "Medical technology innovation, translation and convergence"
    }
  },
  {
    "item": {
      "id": 6,
      "sector": 'Healthcare',
      "expertise": ["Healthcare"],
      "text": "Understanding cardio metabolic disease"
    }
  },
  {
    "item": {
      "id": 7,
      "sector": 'Healthcare',
      "expertise": ["Healthcare"],
      "text": "Improving early cancer diagnosis and treatment"
    }
  },
  {
    "item": {
      "id": 8,
      "sector": 'Healthcare',
      "expertise": ["Healthcare", "Pharmaceuticals"],
      "text": "Understanding life in molecular detail"
    }
  },
  {
    "item": {
      "id": 9,
      "sector": 'Healthcare',
      "expertise": ["Healthcare"],
      "text": "Evidencing treatment through clinical trials"
    }
  },
  {
    "item": {
      "id": 10,
      "sector": 'Engineering',
      "expertise": ["Energy", "Transport"],
      "text": "Optimising energy systems"
    }
  },
  {
    "item": {
      "id": 11,
      "sector": 'Engineering',
      "expertise": ["Energy"],
      "text": "Enhancing petroleum recovery"
    }
  },
  {
    "item": {
      "id": 12,
      "sector": 'Engineering',
      "expertise": ["Transport"],
      "text": "High speed rail and system integration innovation"
    }
  },
  {
    "item": {
      "id": 13,
      "sector": 'Engineering',
      "expertise": ["Healthcare", "Electronics"],
      "text": "Terahertz frequency electronic and photonic devices"
    }
  },
  {
    "item": {
      "id": 14,
      "sector": 'Engineering',
      "expertise": ["Healthcare", "Transport", "Manufacturing"],
      "text": "Human-centred robotic and autonomous systems"
    }
  },
  {
    "item": {
      "id": 15,
      "sector": 'Engineering',
      "expertise": ["Healthcare", "Energy", "Transport", "Manufacturing"],
      "text": "Surface engineering across the length scales"
    }
  },
  {
    "item": {
      "id": 16,
      "sector": 'Engineering',
      "expertise": ["Pharmaceuticals", "Manufacturing"],
      "text": "Chemical and process engineering from molecule to product"
    }
  },
  {
    "item": {
      "id": 17,
      "sector": 'Engineering',
      "expertise": ["Pharmaceuticals"],
      "text": "Bionanotechnology for disease diagnosis, treatment and prevention"
    }
  },
  {
    "item": {
      "id": 18,
      "sector": 'Engineering',
      "expertise": ["Healthcare", "Pharmaceuticals", "Electronics", "Manufacturing"],
      "text": "Engineering materials at the atomic level"
    }
  },
  {
    "item": {
      "id": 19,
      "sector": 'Environment',
      "expertise": ["Healthcare", "Environment & Food"],
      "text": "Addressing global challenges in food security"
    }
  },
  {
    "item": {
      "id": 20,
      "sector": 'Environment',
      "expertise": ["Healthcare", "Environment & Food"],
      "text": "Interdisciplinary approaches to tackling major water issues"
    }
  },
  {
    "item": {
      "id": 21,
      "sector": 'Environment',
      "expertise": ["Cities"],
      "text": "Designing cities of the future"
    }
  },
  {
    "item": {
      "id": 22,
      "sector": 'Environment',
      "expertise": ["Transport", "Cities"],
      "text": "Europe’s leading city simulation capability"
    }
  },
  {
    "item": {
      "id": 23,
      "sector": 'Environment',
      "expertise": ["Environment & Food"],
      "text": "Robust and timely climate solutions"
    }
  }
];

let expertise;
let res = items.reduce((acc, {
  item: {
    expertise,
    text
  }
}) => {
  expertise.forEach(x => acc[x] = [...(acc[x] || []), text]);
  return acc;
}, {});


Object.entries(res).forEach(([k, v]) => {
  console.log(k + "\n->" + v.join("\n->"));
});


Solution

  • You need one more level for the sectors:

    var items = [{"item": {"id": 0,"sector": 'Data',"expertise": ["Healthcare"],"text": "Data-driven insights to improve healthcare"}},{"item": {"id": 1,"sector": 'Data',"expertise": ["Energy", "Transport", "Cities"],"text": "Urban Analytics"}},{"item": {"id": 2,"sector": 'Data',"expertise": ["Energy", "Transport", "Consumer"],"text": "Understanding patterns of consumer behaviour"}},{"item": {"id": 3,"sector": 'Data',"expertise": ["Healthcare", "Consumer"],"text": "Novel data mining and visualisation"}},{"item": {"id": 4,"sector": 'Data',"expertise": ["Healthcare", "Transport", "Consumer"],"text": "Human-centred augmented and virtual realities"}},{"item": {"id": 5,"sector": 'Healthcare',"expertise": ["Healthcare"],"text": "Medical technology innovation, translation and convergence"}},{"item": {"id": 6,"sector": 'Healthcare',"expertise": ["Healthcare"],"text": "Understanding cardio metabolic disease"}},{"item": {"id": 7,"sector": 'Healthcare',"expertise": ["Healthcare"],"text": "Improving early cancer diagnosis and treatment"}},{"item": {"id": 8,"sector": 'Healthcare',"expertise": ["Healthcare", "Pharmaceuticals"],"text": "Understanding life in molecular detail"}},{"item": {"id": 9,"sector": 'Healthcare',"expertise": ["Healthcare"],"text": "Evidencing treatment through clinical trials"}},{"item": {"id": 10,"sector": 'Engineering',"expertise": ["Energy", "Transport"],"text": "Optimising energy systems"}},{"item": {"id": 11,"sector": 'Engineering',"expertise": ["Energy"],"text": "Enhancing petroleum recovery"}},{"item": {"id": 12,"sector": 'Engineering',"expertise": ["Transport"],"text": "High speed rail and system integration innovation"}},{"item": {"id": 13,"sector": 'Engineering',"expertise": ["Healthcare", "Electronics"],"text": "Terahertz frequency electronic and photonic devices"}},{"item": {"id": 14,"sector": 'Engineering',"expertise": ["Healthcare", "Transport", "Manufacturing"],"text": "Human-centred robotic and autonomous systems"}},{"item": {"id": 15,"sector": 'Engineering',"expertise": ["Healthcare", "Energy", "Transport", "Manufacturing"],"text": "Surface engineering across the length scales"}},{"item": {"id": 16,"sector": 'Engineering',"expertise": ["Pharmaceuticals", "Manufacturing"],"text": "Chemical and process engineering from molecule to product"}},{"item": {"id": 17,"sector": 'Engineering',"expertise": ["Pharmaceuticals"],"text": "Bionanotechnology for disease diagnosis, treatment and prevention"}},{"item": {"id": 18,"sector": 'Engineering',"expertise": ["Healthcare", "Pharmaceuticals", "Electronics", "Manufacturing"],"text": "Engineering materials at the atomic level"}},{"item": {"id": 19,"sector": 'Environment',"expertise": ["Healthcare", "Environment & Food"],"text": "Addressing global challenges in food security"}},{"item": {"id": 20,"sector": 'Environment',"expertise": ["Healthcare", "Environment & Food"],"text": "Interdisciplinary approaches to tackling major water issues"}},{"item": {"id": 21,"sector": 'Environment',"expertise": ["Cities"],"text": "Designing cities of the future"}},{"item": {"id": 22,"sector": 'Environment',"expertise": ["Transport", "Cities"],"text": "Europe’s leading city simulation capability"}},{"item": {"id": 23,"sector": 'Environment',"expertise": ["Environment & Food"],"text": "Robust and timely climate solutions"}}];
    
    const res = items.reduce((acc, {item: {sector, expertise, text}}) => {
        expertise.forEach(exp => {
            acc[exp] = acc[exp] || {};
            acc[exp][sector] = [...(acc[exp][sector] || []), text];
        });
        return acc;
    }, {});
    
    Object.entries(res).forEach(([exp, sectors]) => {
        console.log("- " + exp);
        Object.entries(sectors).forEach(([sector, texts]) => {
            console.log("-- " + sector + "\n--- " + texts.join("\n--- "));
        });
    });

    Explanation

    In the reduce operation, the sector is also grabbed from the object. Just like in the original, the expertises are iterated over, but now the acc object becomes a two-level object instead of just one level. The first level properties are the expertises (exp). If such property does not exist yet, it gets an empty object as value:

            acc[exp] = acc[exp] || {};
    

    The line that follows is much like you already had it: the next property level consists of the sectors, and for each sector an array of texts is maintained.

    The second part of the code applies the same principle as you already had it, but again with an extra level. First the expertise properties are iterated over. They have objects as values, each having sector properties. The inner loop is then again much like you had it: for each sector the sector and associated text values are displayed.