Ich habe ein Array wie folgt:

[
{customer: bryan, id: 123, consultant: Dave, consultantID: 400}
{customer: sharon, id: 124, consultant: Dave, consultantID: 400}
{customer: bobby, id: 125, consultant: Simon, consultantID: 401} 
{customer: chris, id: 126, consultant: Dave, consultantID: 400} 
{customer: sanji, id: 127, consultant: Lars, consultantID: 402}
]

Ich versuche, ein Array zu erstellen, das die Kunden nach Berater gruppiert und die Berater-ID wie folgt als Eigenschaft enthält:

[
{consultant: Dave, count: 3, consultantID: 400}
{consultant: Simon, count: 1, consultantID: 401}
{consultant: Lars, count: 1, consultantID: 402}
]

Zuvor habe ich im Projekt ein Groupby-Addon verwendet, um Informationen zu sammeln. Dies funktioniert gut, um die Kunden pro Berater zu zählen, aber ich kann nicht sowohl den Namen als auch die ID übernehmen.

Ich habe versucht, ein forEach für das Array zu verwenden, das dem folgenden ähnelt:

function(){
  let newArray = []
    let patientCount = 0;
    this.get('customerArray').forEach(function(x) {
      let name = x.consultant_name
      let id = x.consultant_id
      let newData = {
        consultantName: name,
        consultantID: id,
      }
      patientCount++
      newArray.push(newData)
    })
    return newArray
}

Dies ergibt jedoch (offensichtlich) eine Rendite pro Datensatz, und ich bin mir nicht sicher, wie ich diese Art von Funktion strukturieren muss. Ich vermute, dass ich möglicherweise mehrere Schleifen verschachteln muss, aber ich bin mit diesem Prozess nicht vertraut, da ich neu in Javascrtip bin

Jede Hilfe wird geschätzt

Bearbeiten: Dies ist die Implementierung von Denys Antwort als Ember Computed-Eigenschaft.

conTable: computed('conData', function(){
  let array = this.get('conData')
  let grouped = Object.values(array.reduce((s, e)=>{
       let c = s[e.consultantID];
       if (!c) {
             c = s[e.consultantID] = {
                consultant: e.consultant,
                consultantId: e.consultantID,
                count: 0
             };
       }
       c.count++;
       return s;
  }, {}));
return grouped
    }),
-1
Sorvah 19 Apr. 2018 im 11:08

3 Antworten

Beste Antwort

Der grundlegende Ansatz für diese Problemfamilie besteht im Allgemeinen darin, eine Karte (oder ein Objekt als Karte) zu verwenden, deren Schlüssel die ID ist, auf der Sie gruppieren möchten, und reduziere dein Array in diese Map.

let src = [
{customer: "bryan", id: 123, consultant: "Dave", consultantID: 400},
{customer: "sharon", id: 124, consultant: "Dave", consultantID: 400},
{customer: "bobby", id: 125, consultant: "Simon", consultantID: 401}, 
{customer: "chris", id: 126, consultant: "Dave", consultantID: 400},
{customer: "sanji", id: 127, consultant: "Lars", consultantID: 402}
];

let grouped = Object.values(src.reduce((s, e)=>{
     let c = s[e.consultantID];
     if (!c) {
           c = s[e.consultantID] = {
              consultant: e.consultant,
              consultantId: e.consultantID,
              count: 0
           };
     }
     c.count++;
     return s;
}, {}));

console.log("result:", grouped);
1
Denys Séguret 19 Apr. 2018 im 08:16

Sie können eine Funktion mit dem Array, dem Schlüssel und den gewünschten Eigenschaften als Parameter verwenden und eine Map für eine Sammlung derselben gewünschten Eigenschaft.

function groupBy(array, key, properties) {
    var map = new Map;

    array.forEach(o => {
        if (map.has(o[key])) {
            map.get(o[key]).count++;
            return;
        }
        map.set(o[key], Object.assign(...properties.map(k => ({ [k]: o[k] })), { count: 1 }));
    });
    return Array.from(map.values());
}

var data = [{ customer: 'bryan', id: 123, consultant: 'Dave', consultantID: 400 }, { customer: 'sharon', id: 124, consultant: 'Dave', consultantID: 400 }, { customer: 'bobby', id: 125, consultant: 'Simon', consultantID: 401 }, { customer: 'chris', id: 126, consultant: 'Dave', consultantID: 400 }, { customer: 'sanji', id: 127, consultant: 'Lars', consultantID: 402 }];

console.log(groupBy(data, 'consultantID', ['consultant', 'consultantID']));
.as-console-wrapper { max-height: 100% !important; top: 0; }
1
Nina Scholz 19 Apr. 2018 im 08:29

ES6

Sie können auch reduce() , some(), filter() und die spread syntax um das gewünschte Ergebnis zu erhalten.

DEMO

const arr=[
{customer: 'bryan', id: 123, consultant: 'Dave', consultantID: 400},
{customer: 'sharon', id: 124, consultant: 'Dave', consultantID: 400},
{customer: 'bobby', id: 125, consultant: 'Simon', consultantID: 401} ,
{customer: 'chris', id: 126, consultant: 'Dave', consultantID: 400} ,
{customer: 'sanji', id: 127, consultant: 'Lars', consultantID: 402}
]

let result = arr.reduce((r, {consultantID,consultant}) => {
    if (!r.some(o => o.consultantID == consultantID)) {
        r.push({consultantID,consultant,count: arr.filter(v => v.consultantID == consultantID).length});
    }
    return r;
}, []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
1
Narendra Jadhav 19 Apr. 2018 im 08:35