Рефакторинг 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 на строки компании, поэтому они соответствуют свойствам.

Другие вопросы по тегам