我有一个包含字符串和整数的二维数组。 在GAS中,我想创建一个新数组,该数组对具有公共字符串的数组的整数求平均值。
我一直在寻找解决方案,但是我发现的大部分内容都在ES6上,而GAS不支持ES6,其余的我无法适应我的情况。
我尝试使用map,reduce和filter,但是找不到合适的解决方案。
下面是数组和所需输出的示例。
function myfunction(){
var array = [
["House1", 1.0, 2.0, 5.0, 1.0],
["House1", 1.0, 4.0, 2.0, 3.0],
["House2", 2.0, 3.0, 3.0, 4.0],
["House2", 5.0, 4.0, 3.0, 4.0],
["House2", 4.0, 5.0, 2.0, 2.0],
["House3", 2.0, 1.0, 4.0, 5.0]]
}
//Desired output
var newArray = [
["House1", 1.0, 3.0, 3.5, 2.0],
["House2", 3.6, 4.0, 2.6, 3.3],
["House3", 2.0, 1.0, 4.0, 5.0]
]
答案 0 :(得分:0)
let array = [
["House1", 1.0, 2.0, 5.0, 1.0],
["House1", 1.0, 4.0, 2.0, 3.0],
["House2", 2.0, 3.0, 3.0, 4.0],
["House2", 5.0, 4.0, 3.0, 4.0],
["House2", 4.0, 5.0, 2.0, 2.0],
["House3", 2.0, 1.0, 4.0, 5.0]];
let averageArrays = arrays =>
arrays.reduce((sum, a) => {
a.forEach((v, i) => sum[i] = (sum[i] || 0) + v / arrays.length);
return sum;
}, []);
let grouped = array.reduce((acc, a) => {
acc[a[0]] = acc[a[0]] || [];
acc[a[0]].push(a.slice(1));
return acc;
}, {});
let averages = Object.entries(grouped).map(([name, arrays]) => [name, ...averageArrays(arrays)]);
console.log(averages);
答案 1 :(得分:0)
您可以为相同的组制作一个哈希表,并通过存储总和和计数来获得平均值。
结果是每个组的平均值数组。
function buildAverages(array) {
var hash = {},
result = [],
i, j, item, key;
for (i = 0; i < array.length; i++) {
item = array[i];
key = item[0];
if (!hash[key]) {
hash[key] = { avg: array[i].slice(), sums: array[i].slice(), count: 1 };
result.push(hash[key].avg);
continue;
}
hash[key].count++;
for (j = 1; j < item.length; j++) {
hash[key].sums[j] += item[j];
hash[key].avg[j] = (hash[key].sums[j] / hash[key].count);
}
}
return result;
}
var array = [["House1", 1.0, 2.0, 5.0, 1.0], ["House1", 1.0, 4.0, 2.0, 3.0], ["House2", 2.0, 3.0, 3.0, 4.0], ["House2", 5.0, 4.0, 3.0, 4.0], ["House2", 4.0, 5.0, 2.0, 2.0], ["House3", 2.0, 1.0, 4.0, 5.0]]
console.log(buildAverages(array));
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 2 :(得分:0)
下面的代码在GAS环境中进行了测试。
function myFunction() {
var array = [
["House1", 1.0, 2.0, 5.0, 1.0],
["House1", 1.0, 4.0, 2.0, 3.0],
["House2", 2.0, 3.0, 3.0, 4.0],
["House2", 5.0, 4.0, 3.0, 4.0],
["House2", 4.0, 5.0, 2.0, 2.0],
["House3", 2.0, 1.0, 4.0, 5.0]
];
var avg = {}, count = {};
array.forEach(function(a) {
var key = a.shift();
if (avg[key]) {
for (var i = 0; i < 4; i++) {
avg[key][i] += a[i];
}
count[key]++;
} else {
avg[key] = a;
count[key] = 1;
}
});
var result = [];
for (var key in avg) {
for (var i = 0; i < 4; i++) {
avg[key][i] /= count[key];
}
avg[key].unshift(key);
result.push(avg[key]);
}
Logger.log(result);
}
可能很长,但每个步骤都很明确。我们在 av 和 count 对象中累积中间结果,然后根据需要将其转换为 result 数组。
答案 3 :(得分:0)
为每个房屋创建一个数组的分组对象。取每个组对象并求和,然后对每个对象分别求平均值。
function groupByAndAvg(array) {
var out = {};
array.forEach(function(row) {
var house = row[0];
out[house] = out[house] || [];
out[house].push(row);
});
return Object.keys(out).map(function(thisHouse) {
var house = out[thisHouse];
var l = house.length;
var sumHouse = house.reduce(function(acc, row) {
return acc.map(function(e, i) {
return typeof e === 'number' ? e + row[i] : e;
});
}, house.pop());
return sumHouse.map(function(e) {
return typeof e === 'number' ? e / l : e;
});
});
}
var array = [
['House1', 1.0, 2.0, 5.0, 1.0],
['House1', 1.0, 4.0, 2.0, 3.0],
['House2', 2.0, 3.0, 3.0, 4.0],
['House2', 5.0, 4.0, 3.0, 4.0],
['House2', 4.0, 5.0, 2.0, 2.0],
['House3', 2.0, 1.0, 4.0, 5.0],
];
console.info(groupByAndAvg(array));