2016-09-14 2 views
0

Ich habe mit der Erstellung einer Arbeitszeittabelle beauftragt, die die Stunden von jedem Client pro Tag gearbeitet wird. Die Tabelle sollte unter so etwas wie das Snippet aussehen:Javascript Objekt Array Gruppierung und Summierung

table, td, th { 
 
      border: 1px solid black; 
 
     }
<div> 
 
    <table id="testTable" class="table"> 
 
    <tr> 
 
     <th>Client name</th> 
 
     <th>Monday</th> 
 
     <th>Tuesday</th> 
 
     <th>Wednesday</th> 
 
     <th>Thursday</th> 
 
     <th>Friday</th> 
 
     <th>Saturday</th> 
 
     <th>Sunday</th> 
 
    </tr> 
 
    <tr> 
 
     <td>client1</td> 
 
     <td>0</td> 
 
     <td>5</td> 
 
     <td>3</td> 
 
     <td>2</td> 
 
     <td>3</td> 
 
     <td>0</td> 
 
     <td>0</td> 
 
    </tr> 
 
    <tr> 
 
     <td>client2</td> 
 
     <td>4</td> 
 
     <td>1</td> 
 
     <td>4</td> 
 
     <td>2</td> 
 
     <td>1</td> 
 
     <td>0</td> 
 
     <td>0</td> 
 
    </tr> 
 
    </table> 
 
</div>
Das Problem, das ich habe ist, dass die Zeiterfassungselemente nach der Abfrage erforderlich, um die Tabelle zu füllen, ich bin nicht sicher, wie die einzelnen Elemente zu einer Gruppe durch den Client-Namen und Tag der Woche. Das Array abgerufen würde ähnlich aussehen wie diese:

timesheetItems = [ 
 
    timesheetItem = { 
 
     clientName: client1, 
 
     hoursWorked: 2, 
 
     day: Monday 
 
    }, 
 
    timesheetItem = { 
 
     clientName: client1, 
 
     hoursWorked: 3, 
 
     day: Monday 
 
    }, 
 
    timesheetItem = { 
 
     clientName: client1, 
 
     hoursWorked: 4, 
 
     day: Wednesday 
 
    }, 
 
    timesheetItem = { 
 
     clientName: client2, 
 
     hoursWorked: 4, 
 
     day: Monday 
 
    } 
 
    
 
    ];
die gruppiert Array sollte Gruppe alle Zeiterfassungs Elemente in einem Objekt pro Client und haben Schlüssel für jeden Tag der Woche, dass die Summe der Stunden enthält gearbeitet dieser Tag. Die endgültige Anordnung soll wie folgt aussehen:

groupedArray = { 
 
    Client1 = { 
 
    Mon: 5, 
 
    tues: 3, 
 
    ... 
 
    sun: 0 
 
    }, 
 
    client2 = { 
 
    mon:2, 
 
    ... 
 
    }, 
 
    client3 = { 
 
    ... 
 
    }, 
 
    ... 
 
}

Also wenn jemand könnte vorschlagen, wie etwa die Gruppierung den Zeiterfassungs Artikel Array zu gehen, so dass das Ergebnis oben wie die Schnipsel aussehen wird, so kann ich einfach aus dem gruppierten Array zu loopen, um die Tabelle zu füllen, wäre es sehr hilfreich. Danke.

+0

[Array # verringern] (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) – Xotic750

Antwort

1

Um ein Array aggregieren Sie reduce verwenden können:

const groupedArray = timesheetItems.reduce((prev, curr) => { 
    if (!prev[curr.clientName]) { 
     prev[curr.clientName] = {}; 
    } 
    if (!prev[curr.clientName][curr.day]) { 
     prev[curr.clientName][curr.day] = 0 
    } 
    prev[curr.clientName][curr.day] += curr.hoursWorked; 
    return prev; 
}, {}); 
0

Sie Array#forEach nutzen könnten und für vorhandene Objekte überprüfen. Wenn nicht vorhanden, vergeben Sie ein neues Objekt oder einen neuen Wert.

var timesheetItems = [{ clientName: 'client1', hoursWorked: 2, day: 'Monday' }, { clientName: 'client1', hoursWorked: 3, day: 'Monday' }, { clientName: 'client1', hoursWorked: 4, day: 'Wednesday' }, { clientName: 'client2', hoursWorked: 4, day: 'Monday' }], 
 
    grouped = {}; 
 

 
timesheetItems.forEach(a => { 
 
    grouped[a.clientName] = grouped[a.clientName] || {}; 
 
    grouped[a.clientName][a.day] = (grouped[a.clientName][a.day] || 0) + a.hoursWorked; 
 
}); 
 

 
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }

0

Wir könnten eine tableMaker() Funktion verwenden, um eine Tabelle aus einer Reihe von Objekten zu erzeugen, wobei jedes Objekt eine Tabellenzeile bezeichnen, wobei die Eigenschaften der Objekte bezeichnen die Überschriften und die Werte sind die Daten Zellen. Aber zuerst müssen wir unsere Daten in eine Form konvertieren, die die tableMaker() Funktion verstehen kann. Wie

[ { 'Client Name': 'client1', 
    Monday: 5, 
    Tuesday: 0, 
    Wednesday: 4, 
    Thursday: 0, 
    Friday: 0 }, 
    { 'Client Name': 'client2', 
    Monday: 4, 
    Tuesday: 0, 
    Wednesday: 0, 
    Thursday: 0, 
    Friday: 0 } ] 

Also hier ist der Code für die Tabelle.

function tableMaker(o,h=true){ 
 
    var keys = Object.keys(o[0]), 
 
    rowMaker = (a,t) => a.reduce((p,c,i,a) => p + (i === a.length-1 ? "<" + t + ">" + c + "</" + t + "></tr>" 
 
                    : "<" + t + ">" + c + "</" + t + ">"),"<tr>"), 
 
     rows = o.reduce((r,c) => r + rowMaker(keys.reduce((v,k) => v.concat(c[k]),[]),"td"),h ? rowMaker(keys,"th") : []); 
 
    return "<table>" + rows + "</table>"; 
 
} 
 

 
function giveMeNewClient(o){ 
 
    var templateObject = { 
 
    \t     "Client Name": "", 
 
    \t      "Monday": 0, 
 
    \t      "Tuesday": 0, 
 
    \t     "Wednesday": 0, 
 
    \t     "Thursday": 0, 
 
    \t      "Friday": 0 
 
         }; 
 
    return Object.assign(templateObject,o); 
 
} 
 
var timesheetItems = [{ 
 
         clientName: "client1", 
 
         hoursWorked: 2, 
 
           day: "Monday" 
 
         }, 
 
         { 
 
         \t clientName: "client1", 
 
         hoursWorked: 3, 
 
           day: "Monday" 
 
         }, 
 
         { 
 
         \t clientName: "client1", 
 
         hoursWorked: 4, 
 
           day: "Wednesday" 
 
         }, 
 
         { 
 
         \t clientName: "client2", 
 
         hoursWorked: 4, 
 
           day: "Monday" 
 
         } 
 
        ], 
 

 
     tableData = timesheetItems.reduce((res,c) => { var client = res.find(o => o["Client Name"] === c.clientName); 
 
                 client ? client[c.day]+= c.hoursWorked 
 
                   : res.push(giveMeNewClient({"Client Name": c.clientName, [c.day]: c.hoursWorked})); 
 
                 return res; 
 
                 },[]), 
 
     tableHTML = tableMaker(tableData); 
 
myTable.innerHTML = tableHTML;
<div id="myTable"></div>