代码之家  ›  专栏  ›  技术社区  ›  Tasos

将javascript mutaliarray按索引分组,得到总和和平均值

  •  3
  • Tasos  · 技术社区  · 8 年前

    我有一个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],
    ]
    

    我发现 similar questions

    5 回复  |  直到 8 年前
        1
  •  4
  •   Nina Scholz    8 年前

    您可以获取一个对象并收集值,以便稍后生成平均值。

    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);
        2
  •  1
  •   Eddie    8 年前

    一种选择是使用 .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);
        3
  •  0
  •   gillyhl    8 年前

    下面的可能会帮你。我省略了加法和平均值计算,但下面的代码结构将完成现有数据的匹配。

    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 ]
        }
    }, [])
    
        4
  •  0
  •   kapantzak    8 年前

    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>
        5
  •  0
  •   Hasan Sh    8 年前

    不管你有多少个复制品,这里有一个很好的通用方法:

    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) 输出

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

    Object.values(newArr)