简体   繁体   English

按索引对javascript mutliarray进行分组并得到总和和平均值

[英]Group javascript mutliarray by indexes and get sum and average

I have a multiarray in Javascript with the following format 我在Javascript中有一个多行阵列,格式如下

[ [string, string, string, number, number], ......]

For example 例如

[
['John', 'Apple', 'Monday', 1, 4.5],
 ['John', 'Orange', 'Monday', 2, 3],
 ['John', 'Apple', 'Monday', 1, 2.5]
]

How can I group the above by the first three items (the strings) and get the sum of the first number and the average of the second number? 如何通过前三项(字符串)对上面的内容进行分组,得到第一个数字和第二个数字的平均值之和?

The result of above: 结果如上:

[
['John', 'Apple', 'Monday', 2, 3.5],
 ['John', 'Orange', 'Monday', 2, 3],
]

I used to do this with underscore, but now I need to use just Javascript or jQuery. 我曾经用下划线做这个,但现在我只需要使用Javascript或jQuery。

I found similar questions (not exactly) but didn't help a lot 我发现了类似的问题 (不完全一样),但没有多大帮助

You could take an object and collect the values for later generating the average. 您可以获取一个对象并收集值以便稍后生成平均值。

 var array = [['John', 'Apple', 'Monday', 1, 4.5], ['John', 'Orange', 'Monday', 2, 3], ['John', 'Apple', 'Monday', 1, 2.5]], result = Object .values(array.reduce((r, a) => { var key = a.slice(0, 3).join('|'); if (!r[key]) { r[key] = a.slice().concat(1); return r; } r[key][3] += a[3]; r[key][4] += a[4]; r[key][5]++; return r; }, Object.create(null))) .map(a => a.slice(0, 4).concat(a[4] / a[5])); console.log(result); 

One option is using .reduce() to group the array. 一种选择是使用.reduce()对数组进行分组。 Use .map() and .reduce() to get the total, average and construct the final array. 使用.map().reduce()来获取总数,平均值并构造最终数组。

 let arr = [ ['John', 'Apple', 'Monday', 1, 4.5], ['John', 'Orange', 'Monday', 2, 3], ['John', 'Apple', 'Monday', 1, 2.5] ]; let result = [...arr.reduce((c, v) => { let k = v[0] + v[1] + v[2]; c.set(k, c.has(k) ? [...c.get(k), v] : [v]); return c; }, new Map()).values()].map(o => { let t = o.reduce((c, v) => [c[0] + v[3], c[1] + v[4]], [0, 0]); return [o[0][0], o[0][1], o[0][2], t[0], (t[1] / o.length)]; }); console.log(result); 

The below may do the trick for you. 以下可能会为您解决问题。 I've left out the adding and average calculations, but the below structure of the code will do the matching of existing data. 我省略了添加和平均计算,但下面的代码结构将匹配现有数据。

const comparitorIndexes = [0,1,2]
array.reduce((acc, curr) => {
    const accIndex = acc.findIndex(x => comparitorIndexes.every(i => x[i] === curr[i]))
    if (accIndex > -1) {
        // Do sum and average here and return accumaltor
    } else {
        return [ ...acc, curr ]
    }
}, [])

 var data = [ ['John', 'Apple', 'Monday', 1, 4.5], ['John', 'Orange', 'Monday', 2, 3], ['John', 'Apple', 'Monday', 1, 2.5] ]; function groupData(data) { return data.reduce(function(acc, item) { if (item.length === 5) { var found = false; var lit = item.slice(0,3); var numSum = item.slice(3,4); var numAvg = item.slice(4,5); for (var i in acc) { var accLit = acc[i].slice(0,3); if (accLit[0] === lit[0] && accLit[1] === lit[1] && accLit[2] === lit[2]) { found = true; var accNumSum = acc[i].slice(3,4); var accNumAvg = acc[i].slice(4,5); acc[i][3] = parseFloat(numSum) + parseFloat(accNumSum); acc[i][4] = (parseFloat(numAvg) + parseFloat(accNumAvg)) / 2; } } if (!found) { acc.push(item); } return acc; } }, []); } //function match var result = groupData(data); console.log(result); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 

Here's a nice and generic way, no matter how many duplicates you have, of doing it: 这是一个很好的和通用的方式,无论你有多少重复,这样做:

const arr = [
 ['John', 'Apple', 'Monday', 1, 4.5],
 ['John', 'Orange', 'Monday', 2, 3],
 ['John', 'Apple', 'Monday', 1, 2.5]
]

const newArr = arr.reduce((acc, curr)=> {
const key = `${curr[0]}_${curr[1]}_${curr[2]}`

if (!acc[key]) {
  acc[key] = [];
 }

acc[key].push(curr);
if(acc[key].length > 1) {
  const firstNum = acc[key].map(nestedArr=>  nestedArr[3])
  const secondNum = acc[key].map(nestedArr=> nestedArr[4])

  const sum = firstNum.reduce((a, b)=> a + b)
  const average = secondNum.reduce((a, b)=> (a + b) / 2)

  const newAcc = acc[key][0].slice(0, 3).concat(sum, average)

  acc[key] = [newAcc]
}
return acc;
}, {})

console.log(newArr) Output console.log(newArr)输出

{ John_Apple_Monday: ["John", "Apple", "Monday", 2, 3.5], John_Orange_Monday: ["John", "Orange", "Monday", 2, 3] }

I kept as a key_value because that might also help. 我保留了一个key_value因为这也可能有所帮助。 But you can simply get the keys of that object with Object.values(newArr) 但是您可以使用Object.values(newArr)简单地获取该对象的键

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM