转换对象的JavaScript数组
作者:互联网
我有以下两个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" ];
有没有一种简单的方法,而无需遍历StudentGrads并保持计数和班级的唯一列表?
编辑:发布问题后,我创建了以下代码.我仍然希望采用一种更易读的方式来执行此操作.
<!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.forEach
和Array.prototype.map
之类的函数,可以使它看起来没有循环.
我认为最简单的方法是创建可快速访问所需数据的地图,因此您不必不断扫描数组,也不需要下划线或jQuery之类的帮助器.这些地图的好处是您可以轻松地使用它们来更轻松地生成其他格式的数据.
您可以研究以下内容,这些内容将产生所需的输出,并自行决定是否比使用常规循环更容易.
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]}]
*/
标签:underscore-js,javascript,jquery,kendo-chart 来源: https://codeday.me/bug/20191120/2042530.html