Рефакторинг jQuery для каждого цикла объекта данных
У меня есть файл CSV, преобразованный в объект jQuery с помощью jQuery CSV ( https://github.com/evanplaice/jquery-csv).
Вот код для этого:
$.ajax({
type: "GET",
url: "/path/myfile.csv",
dataType: "text",
success: function(data) {
// once loaded, parse the file and split out into data objects
// we are using jQuery CSV to do this (https://code.google.com/p/jquery-csv/)
var data = $.csv.toObjects(data);
});
Я складываю значения bushels_per_day по компании и хочу реорганизовать мой код, чтобы сделать его более компактным.
Используя этот ответ: Суммируйте значения в объекте jQuery по ключу, я могу циклически использовать $.each();
Формат объекта выглядит так:
var data = [
"0":{
bushels_per_day: "145",
plant_city: "Decatur",
plant_company: "AGP",
},
"1":{
bushels_per_day: "125",
plant_city: "Cedar Rapids",
plant_company: "AGP",
},
"2":{
bushels_per_day: "345",
plant_city: "Ralston",
plant_company: "AGP",
},
"3":{
bushels_per_day: "55",
plant_city: "Dawson",
plant_company: "ADM",
},
"4":{
bushels_per_day: "55",
plant_city: "Dawson",
plant_company: "ADM",
},
// ... more objects
]
А вот цикл $.each ():
var sumADM = 0;
var sumAGP = 0;
// var for each company
$.each(data, function (index, value) {
var capacity = parseInt(value.bushels_per_day, 10);
var company = value.plant_company.replace(/\W+/g, '_').toLowerCase();
if (company == 'adm') {
sumADM += capacity;
}
if (company == 'agp') {
sumAGP += capacity;
}
// ... and so on for each company
});
console.log(sumADM, sumAGP); // and so on.
Это работает, но как я могу реорганизовать это так, чтобы мне не нужна переменная суммы и оператор if для каждой компании? В настоящее время переменная суммы и console.log() должны находиться вне цикла, чтобы возвращать правильные итоги.
Есть ли лучший, более компактный способ сделать это?
1 ответ
Вы можете поместить суммы на объект как свойства:
var sums = {
ADM: 0,
AGP: 0
};
$.each(data, function (index, value) {
var capacity = parseInt(value.bushels_per_day, 10);
var company = value.plant_company.replace(/\W+/g, '_').toUpperCase(); // Note change here
sums[company] += capacity;
});
console.log(sums.ADM, sums.AGP); // and so on.
Или вывести их в цикле:
Object.keys(sums).forEach(function(company) {
console.log(sums[company]);
});
Вы могли бы даже сделать lazy-init, если компании меняются:
var sums = {};
$.each(data, function (index, value) {
var capacity = parseInt(value.bushels_per_day, 10);
var company = value.plant_company.replace(/\W+/g, '_').toUpperCase();
sums[company] = (sums[company] || 0) + capacity;
});
Object.keys(sums).forEach(function(company) {
console.log(sums[company]);
});
Способ sums[company] = (sums[company] || 0) + capacity;
линия работает так, что если мы не видели эту компанию раньше, sums[company]
будет undefined
, поскольку undefined
это фальси, необычайно мощный JavaScript ||
оператор примет значение правого операнда (0
) как его результат. Это также верно, если мы видели company
до и sums[company]
является 0
, но ничего страшного, 0
это 0
, Все остальные значения (1
и такие) правдивы, так sum[company] || 0
будет 1
и такие (значение левого операнда).
Примечание: обратите внимание, я использую toUpperCase
скорее, чем toLowerCase
на строки компании, поэтому они соответствуют свойствам.