重构 jQuery 数据对象上的每个循环

Refactoring jQuery each loop on data object

我使用 jQuery CSV (https://github.com/evanplaice/jquery-csv).

将一个 csv 文件转换为 jQuery 对象

这是相关代码:

    $.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 值,并想重构我的代码以使其更紧凑。

使用这个答案:,我可以使用 $.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.

这行得通,但我如何重构它,以便我不需要每个公司的 sum 变量和 if 语句?目前 sum 变量和 console.log() 必须在循环之外才能 return 正确的总数。

有没有更好、更紧凑的方法来做到这一点?

您可以将总和作为属性放在对象上:

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 的 curiously-powerful || operator 将采用右侧操作数值 (0) 作为其结果。如果我们之前看过company并且sums[company]0,这也是正确的,但是没关系,00。所有其他值(1 等)都是真实的,因此 sum[company] || 0 将是 1 等(左侧操作数的值)。


旁注:注意我在公司字符串上使用 toUpperCase 而不是 toLowerCase,因此它们与属性匹配。