Javascript - Gruppiert ein Array von Objekten nach gemeinsamen Werten mit Bezeichnung

Sep 08 2020

Ich versuche, ein Array von Objekten in ein anderes Array von Objekten umzuwandeln, indem ich nach einem bestimmten Wert gruppiere und diesen Wert als Bezeichnung hinzufüge und ihn aus dem Objekt im neuen Array herausnehme.

Eingabe: So habe ich zum Beispiel dieses Array von Objekten:

let tech = [
  { id: 1, grouping: "Front End", value: "HTML" },
  { id: 2, grouping: "Front End", value: "React" },
  { id: 3, grouping: "Back End", value: "Node" },
  { id: 4, grouping: "Back End", value: "PHP" },
];

Erwartet: Ich möchte herausfinden, wie ich dazu gelangen kann. Dort gibt es eine Beschriftung für jedes der eindeutigen Gruppierungen und Optionsarrays, die die Werte dieser Gruppierung enthalten.

[
  {
    label: "Front End",
    options: [
      { id: 1, value: "HTML" },
      { id: 2, value: "React" },
    ],
  },
  {
    label: "Back End",
    options: [
      { id: 3, value: "Node" },
      { id: 4, value: "PHP" },
    ],
  },
]

Das nächste, was ich erreichen konnte, ist die Verwendung von Reduzieren auf Gruppieren mit dem Gruppierungsschlüssel:

const groupedTech = tech.reduce((acc, value) => {
  // Group initialization
  if (!acc[value.grouping]) {
    acc[value.grouping] = [];
  }
 
  // Grouping
  acc[value.grouping].push(value);
 
  return acc;
}, {});

Welches gibt mir das:

{
  "Front End": [
    { id: 1, grouping: "Front End", value: "HTML" },
    { id: 2, grouping: "Front End", value: "React" },
  ],
  "Back End": [
    { id: 3, grouping: "Back End", value: "Node" },
    { id: 4, grouping: "Back End", value: "PHP" },
  ],
}

Dies gibt jedoch kein Objekt zurück und entfernt den Gruppierungswert nicht. Ich konnte nicht herausfinden, wie man richtig gruppiert, weil ich in dem Array von Objekten keinen effizienten Vergleich gefunden habe, um festzustellen, ob die Gruppierung vorhanden ist, und wenn ja, zu diesem verschachtelten Array hinzuzufügen. Wäre es besser für mich, etwas wie .map () zu verwenden ? Schätzen Sie alle Hinweise / Erkenntnisse!

Antworten

3 HaoWu Sep 08 2020 at 12:18

Sie sind sehr nah dran, wickeln Sie einfach die Schlüsselwerteinträge des Ergebnisses in eine mapFunktion ein:

let tech = [
  { id: 1, grouping: "Front End", value: "HTML" },
  { id: 2, grouping: "Front End", value: "React" },
  { id: 3, grouping: "Back End", value: "Node" },
  { id: 4, grouping: "Back End", value: "PHP" },
];

const groupedTech = Object.entries(
  // What you have done
  tech.reduce((acc, { id, grouping, value }) => {
    // Group initialization
    if (!acc[grouping]) {
      acc[grouping] = [];
    }
    
    // Grouping
    // FIX: only pushing the object that contains id and value
    acc[grouping].push({ id, value });

    return acc;
  }, {})
).map(([label, options]) => ({ label, options }));

console.log(groupedTech);

2 hgb123 Sep 08 2020 at 12:18

Sie müssen nur noch eine Manipulation mit Object.entriesund durchführen.map

let tech = [
  { id: 1, grouping: 'Front End', value: 'HTML' },
  { id: 2, grouping: 'Front End', value: 'React' },
  { id: 3, grouping: 'Back End', value: 'Node' },
  { id: 4, grouping: 'Back End', value: 'PHP' }
]

const groupedTech = tech.reduce((acc, value) => {
  // Group initialization
  if (!acc[value.grouping]) {
    acc[value.grouping] = []
  }

  // Grouping
  acc[value.grouping].push(value)

  return acc
}, {})

const res = Object.entries(groupedTech).map(([label, options]) => ({
  label,
  options
}))

console.log(res)

2 Nick Sep 08 2020 at 12:23

Eine geringfügige Abweichung von den beiden anderen Antworten, wenn Sie genau die von Ihnen angegebene Ausgabe erhalten möchten :

let tech = [{
    id: 1,
    grouping: "Front End",
    value: "HTML"
  },
  {
    id: 2,
    grouping: "Front End",
    value: "React"
  },
  {
    id: 3,
    grouping: "Back End",
    value: "Node"
  },
  {
    id: 4,
    grouping: "Back End",
    value: "PHP"
  },
];

const groupedTech = Object.entries(
    tech.reduce((acc, value) => {
      // Group initialization
      if (!acc[value.grouping]) {
        acc[value.grouping] = [];
      }

      // Grouping
      acc[value.grouping].push({
        id: acc[value.grouping].length+1,
        value: value.value
      });

      return acc;
    }, {}))
  .map(([label, options]) => ({
    label,
    options
  }));

console.log(groupedTech);

2 Phil Sep 08 2020 at 12:25

Normalerweise mag ich es, ein MapSchlüssel / Wert-Paar aufzubauen und diese Einträge dann in das Endergebnis umzuwandeln (normalerweise mit Array.prototype.map()oder Array.from()).

const tech = [
  { id: 1, grouping: "Front End", value: "HTML" },
  { id: 2, grouping: "Front End", value: "React" },
  { id: 3, grouping: "Back End", value: "Node" },
  { id: 4, grouping: "Back End", value: "PHP" },
];

const groupedMap = tech.reduce((map, { grouping, ...option }) => {
  if (!map.has(grouping)) {
    map.set(grouping, [])
  }
  map.get(grouping).push(option)
  return map
}, new Map())

const groupedTech = Array.from(groupedMap, ([ label, options ]) => ({
  label,
  options
}))

console.log(groupedTech)

2 charlietfl Sep 08 2020 at 12:37

Verwenden einer Karte und Map # -Werte ()

const grouped = tech.reduce((m,{grouping:label, ...rest})=>{
    const group = m.get(label) || {label, options:[]};
    group.options.push({...rest})
    return m.set(label, group)
},new Map)

console.log([...grouped.values()])
<script>
let tech=[{id:1,grouping:"Front End",value:"HTML"},{id:2,grouping:"Front End",value:"React"},{id:3,grouping:"Back End",value:"Node"},{id:4,grouping:"Back End",value:"PHP"}];
</script>