【问题标题】:Refactoring jQuery each loop on data object在数据对象上重构jQuery每个循环
【发布时间】:2015-03-28 18:49:48
【问题描述】:

我有一个使用 jQuery CSV (https://github.com/evanplaice/jquery-csv) 转换为 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 值相加,并希望重构我的代码以使其更紧凑。

使用这个答案:Sum values in jQuery object by key,我可以循环使用 $.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() 必须在循环之外才能返回正确的总数。

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

【问题讨论】:

  • 您的data 变量格式无效,数组不能有键

标签: jquery object refactoring each jquery-csv


【解决方案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]);
});

如果公司不同,您甚至可以进行惰性初始化:

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,因此它们与属性匹配。

【讨论】:

  • 是的,对不起,我对对象使用了数组表示法。 @T.J 这是完美的。谢谢。
  • 我正在使用toLowerCase(),因为我想将每个值附加到具有每个公司 ID 的 div 中。因此,虽然这可以正确输出数据,但这是行不通的:$('#' + sums[company]).append('<span>Capacity: ' + sums[company] + 'K bushels per day</span>');。我该怎么做?
  • @joshuaiz:好吧,你的 ID 不是 sum,是吗?我在想:$('#' + company.toLowerCase()).append('<span>Capacity: ' + sums[company] + 'K bushels per day</span>'); 或者当然,只使用小写字母而不是大写字母,然后使用 $('#' + company).append('<span>Capacity: ' + sums[company] + 'K bushels per day</span>');
  • 是的,这是一个愚蠢的错误——咖啡不够 :) 但问题是,如果我在循环中使用它,它会返回每个公司的所有迭代,而不是总数。如果我在循环之外使用它,我会收到“公司未定义”错误。
  • @joshuaiz:看看我在“或者在循环中输出它们”之后显示的代码。你会在 $.each 循环之后这样做。
猜你喜欢
  • 2016-10-24
  • 1970-01-01
  • 2019-01-01
  • 2015-05-11
  • 2014-06-17
  • 2014-02-14
  • 1970-01-01
  • 2015-04-04
  • 2017-05-10
相关资源
最近更新 更多