簡體   English   中英

轉換JavaScript對象數組

[英]Transforming a JavaScript array of objects

我有以下兩個JavaScript數組:

var grades = [ { name: "A", color: "#00FF00" }, 
               { name: "B", color: "#88CC00" },
               { name: "C", color: "#AAAA00" }, 
               { name: "D", color: "#CC8800" }, 
               { name: "F", color: "#FF0000" }];

var studentGrades = [ { Student: "James", Class: "Math", Grade: "A" },
                      { Student: "Lily", Class: "Math", Grade: "B" },
                      { Student: "Bob", Class: "Math", Grade: "C" },
                      { Student: "Tom", Class: "Math", Grade: "C" },
                      { Student: "James", Class: "Science", Grade: "A" },
                      { Student: "Lily", Class: "Science", Grade: "B" },
                      { Student: "Bob", Class: "Science", Grade: "B" },
                      { Student: "Tom", Class: "Science", Grade: "B" },
                      { Student: "James", Class: "Chemistry", Grade: "F" },
                      { Student: "Lily", Class: "Chemistry", Grade: "A" },
                      { Student: "Bob", Class: "Chemistry", Grade: "B" },
                      { Student: "Tom", Class: "Chemistry", Grade: "A" } ];

我試圖從它生成以下兩個數組:

grades = [ { name: "A", color: "#00FF00", data: [1, 1, 2] },
                    { name: "B", color: "#88CC00", data: [1, 3, 1] },
                    { name: "C", color: "#AAAA00", data: [2, 0, 0] },
                    { name: "D", color: "#CC8800", data: [0, 0, 0] },
                    { name: "F", color: "#FF0000", data: [0, 0, 1] } ];

var classes = [ "Math", "Science", "Chemistry" ];

有沒有一種簡單的方法可以在不循環studentGrades並保持計數和一個獨特的類列表的情況下做到這一點?

編輯:我在發布問題后創建了以下代碼。 我仍然更喜歡一種更容易閱讀的方法。

<!DOCTYPE html>
<html>
  <head>
    <base href="http://demos.telerik.com/kendo-ui/bar-charts/local-data-binding">
    <style>html { font-size: 12px; font-family: Arial, Helvetica, sans-serif; }</style>
    <title></title>
    <link rel="stylesheet" href="http://cdn.kendostatic.com/2015.1.429/styles/kendo.common-bootstrap.min.css" />
    <link rel="stylesheet" href="http://cdn.kendostatic.com/2015.1.429/styles/kendo.bootstrap.min.css" />
    <link rel="stylesheet" href="http://cdn.kendostatic.com/2015.1.429/styles/kendo.dataviz.min.css" />
    <link rel="stylesheet" href="http://cdn.kendostatic.com/2015.1.429/styles/kendo.dataviz.bootstrap.min.css" />

    <script src="http://cdn.kendostatic.com/2015.1.429/js/jquery.min.js"></script>
    <script src="http://cdn.kendostatic.com/2015.1.429/js/kendo.all.min.js"></script>
  </head>
  <body>
    <div id="example">
      <div class="demo-section k-content">
        <div id="chart"></div>
      </div>
      <script>

        // Start of code that is specific to the stackoverflow question

        var grades = [ { name: "A", color: "#00FF00" }, 
                       { name: "B", color: "#88CC00" },
                       { name: "C", color: "#AAAA00" }, 
                       { name: "D", color: "#CC8800" }, 
                       { name: "F", color: "#FF0000" }];

        var studentGrades = [ { Student: "James", Class: "Math", Grade: "A" },
                              { Student: "Lily", Class: "Math", Grade: "B" },
                              { Student: "Bob", Class: "Math", Grade: "C" },
                              { Student: "Tom", Class: "Math", Grade: "C" },
                              { Student: "James", Class: "Science", Grade: "A" },
                              { Student: "Lily", Class: "Science", Grade: "B" },
                              { Student: "Bob", Class: "Science", Grade: "B" },
                              { Student: "Tom", Class: "Science", Grade: "B" },
                              { Student: "James", Class: "Chemistry", Grade: "F" },
                              { Student: "Lily", Class: "Chemistry", Grade: "A" },
                              { Student: "Bob", Class: "Chemistry", Grade: "B" },
                              { Student: "Tom", Class: "Chemistry", Grade: "A" } ];

        var classes = [];

        // Returns an array that maintains the grade counts for each class based on the grades array.
        var getGradeCounts = function (studentData, gradeCounts) {
            if (gradeCounts == null) {
                gradeCounts = [];
            }
            for (var i = 0; i < grades.length; i++) {
                if (gradeCounts[i] == undefined) {
                    gradeCounts[i] = 0;
                }
                if (grades[i].name === studentData.Grade) {
                    gradeCounts[i]++;
                }
            }
            return gradeCounts;
        }

        // Iterates over each student grade and maintains an object of the grade counts by class, and an unique array of classes used for the chart category.
        var classGradeCounts = {};
        for (var student in studentGrades) {
            var studentClass = studentGrades[student].Class;
            if (classGradeCounts[studentClass] == undefined) {
                classes.push(studentClass);
            }
            classGradeCounts[studentClass] = getGradeCounts(studentGrades[student], classGradeCounts[studentClass]);
        }

        // Now that we have the grade counts for each class, build up the chart series
        for (var i = 0; i < grades.length; i++) {
            grades[i].data = [];
            for (var classGradeCount in classGradeCounts) {
                grades[i].data.push(classGradeCounts[classGradeCount][i]);
            }
        }

        // End of stackoverflow code, the rest of this is code is used to generate a Kendo chart.

        var chartSettings = {
            seriesDefaults: { type: "column", stack: true },
            series: grades,
            categoryAxis: { categories: classes },
        };

        function createChart() {
          $("#chart").kendoChart(chartSettings);
        }

        $(document).ready(createChart);
        $(document).bind("kendo:skinChange", createChart);
      </script>
    </div>


  </body>
</html>

你無法避免循環。 通過使用Array.prototype.forEachArray.prototype.map等函數,可以使它看起來沒有循環。

我相信最簡單的方法是創建可以快速訪問所需數據的地圖,這樣您就不必經常掃描數組,也不需要像underscorejQuery這樣的幫助程序。 這些地圖的好處是您可以輕松地使用它們以更加輕松的方式生成不同格式的數據。

您可以研究產生所需輸出的以下內容,並自行決定是否比使用常規循環更容易。

 var grades = [ { name: "A", color: "#00FF00" }, { name: "B", color: "#88CC00" }, { name: "C", color: "#AAAA00" }, { name: "D", color: "#CC8800" }, { name: "F", color: "#FF0000" }]; var studentGrades = [ { Student: "James", Class: "Math", Grade: "A" }, { Student: "Lily", Class: "Math", Grade: "B" }, { Student: "Bob", Class: "Math", Grade: "C" }, { Student: "Tom", Class: "Math", Grade: "C" }, { Student: "James", Class: "Science", Grade: "A" }, { Student: "Lily", Class: "Science", Grade: "B" }, { Student: "Bob", Class: "Science", Grade: "B" }, { Student: "Tom", Class: "Science", Grade: "B" }, { Student: "James", Class: "Chemistry", Grade: "F" }, { Student: "Lily", Class: "Chemistry", Grade: "A" }, { Student: "Bob", Class: "Chemistry", Grade: "B" }, { Student: "Tom", Class: "Chemistry", Grade: "A" } ]; var gradeMap={}, gradesByClass={}, classMap={}, classArray=[], classIndex=0; grades.forEach(function(grade) { gradeMap[grade.name] = grade.color; }); studentGrades.forEach(function(studentGrade){ if (!gradesByClass[studentGrade.Class]) { gradesByClass[studentGrade.Class] = {}; classMap[studentGrade.Class] = classIndex; classIndex++; } if(!gradesByClass[studentGrade.Class][studentGrade.Grade]) { gradesByClass[studentGrade.Class][studentGrade.Grade] = 0; } gradesByClass[studentGrade.Class][studentGrade.Grade]++; }); Object.keys(classMap).forEach(function(className){ classArray[classMap[className]] = className; }); var finalGrades = Object.keys(gradeMap).map(function(grade){ var obj = { name: grade, color: gradeMap[grade], data: [] }; classArray.forEach(function(className, index){ if (gradesByClass[className] && gradesByClass[className][grade]) { obj.data[index] = gradesByClass[className][grade]; } else { obj.data[index] = 0; } }); return obj; }); console.log(JSON.stringify(finalGrades)); /* [{"name":"A","color":"#00FF00","data":[1,1,2]}, {"name":"B","color":"#88CC00","data":[1,3,1]}, {"name":"C","color":"#AAAA00","data":[2,0,0]}, {"name":"D","color":"#CC8800","data":[0,0,0]}, {"name":"F","color":"#FF0000","data":[0,0,1]}] */ 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM