Как группировать и подсчитывать данные массива по определенному критерию?
У меня скрипт, который считывает идентичные значения по странам и по идентичной стране проводит операции, т.е. там где Италия значения с колонки D вычитает значения по Италии с колонок B и F, а новое значение уже в целом по Италии вставляет в новый диапазон где столбцы G и H и так по остальным странам. Не понимаю, мой скрипт не фильтрует идентичные значения, и я не понимаю, что делать дальше.
https://docs.google.com/spreadsheets/d/1v1fOkfyhmcvndLqJQE7l1et9fjAc21v82lyLarYj60g/edit#gid=0
function Balance() {
let ss = SpreadsheetApp.getActiveSpreadsheet();
let sheet = ss.getSheetByName('data');
let lr = sheet.getLastRow();
let range = sheet.getRange(2, 1, lr, 6).getValues();
let setrange = sheet.getRange(2, 7, lr, 2).setValues(newarr);
let newarr = range.map(calc);
}
function calc(item) {
return [item[2] + item[3] - item[5]];
}
Ответы (1 шт):
В таких задачах мне нравится использовать преобразование массивов к массивам объектов, чтобы не следить за порядком колонок и не думать, куда добавлять результат. Основное решение заключается в том, чтобы собрать уникальные ключи через reduce и пересчитать для каждого вхождения результат. Также можно считать суммы, количество и т.п.
function groupOperationsByAppsScript() {
const sheet = SpreadsheetApp.getActive().getSheetByName('Групповые операции скриптами');
const values = toCollection_(sheet.getDataRange().getValues());
const data = values.reduce((a, c) => {
const outs = c['направление расходов'].__val;
if (outs) {
if (!a[outs])
a[outs] = {
result: 0,
};
a[outs].result += c['расходы'].__val;
}
const ins = c['направление прибыли'].__val;
if (ins) {
if (!a[ins])
a[ins] = {
result: 0,
};
a[ins].result += c['прибыль'].__val;
}
const adins = c['направление доп. расходов'].__val;
if (adins) {
if (!a[adins])
a[adins] = {
result: 0,
};
a[adins].result -= c['доп. расходы'].__val;
}
return a;
}, {});
const directs = [];
const balance = [];
Object.keys(data)
.sort()
.forEach((key) => {
directs.push([key]);
balance.push([data[key].result]);
});
sheet.getRange(2, values[0]['направление'].__col, directs.length, directs[0].length).setValues(directs);
sheet.getRange(2, values[0]['баланс'].__col, balance.length, balance[0].length).setValues(balance);
}
Преобразование строки в объект
function toCollection_(array) {
return array.slice(1).map(
(_, rowIndex) =>
array[0].reduce((rowCollection, header, columnIndex) => {
rowCollection[
String(header)
.toLowerCase()
.replace(/[\r\n]+/g, ' ') || `__col${columnIndex}`
] = {
__col: columnIndex + 1,
__row: rowIndex + 2,
__val: array[rowIndex + 1][columnIndex],
};
return rowCollection;
}, {}),
[],
);
}
Пример данных и рабочий код в Таблице https://docs.google.com/spreadsheets/d/1MqeW7LkEUcsDH8lUksXBLHWmSeu8up2Jr_3ujVwE4SE/edit#gid=1914353719&range=A1
