按索引对JavaScript多维数组进行分组,并获取总和和平均值

3

我有一个Javascript的多维数组,格式如下:

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

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

如何按照前三项(字符串)对上述内容进行分组,并得出第一个数字的总和和第二个数字的平均值?

以上问题的答案为:

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

我以前用underscore做这个,但现在我需要只使用JavaScript或jQuery。

我找到了类似的问题(不完全相同),但没有什么帮助。


你能否将数据保存为对象? - Arunprasanth K V
这是另一个我编写的函数的输出,所以是的。只要最终可以得到多维数组而不是对象,我可以在此过程中将其更改为对象。 - Tasos
你能看一下这个链接吗?https://codereview.stackexchange.com/questions/141530/calculate-average-of-array-of-objects-per-key-value-using-reduce - saumil_
5个回答

4
你可以取一个对象,收集值以便稍后生成平均值。

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);


魔法。非常感谢! - Tasos

1

一种选择是使用.reduce()来对数组进行分组。使用.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);


0
以下代码可能适合您。我省略了添加和平均计算,但是下面的代码结构将匹配现有数据。
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 ]
    }
}, [])

0

这是一种不错且通用的方法,无论你有多少个重复项,都可以使用:

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

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

我将其保留为键值,因为这可能也有帮助。但是您可以使用Object.values(newArr)简单地获取该对象的键。


0

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>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接