2017-02-15 50 views
0

我有以下代码,它工作得很好。 我只是想知道是否有一个更优雅/优化的方式。JavaScript 2D数组分组:是否有更优雅/最优化的方式?

龙“码”短,中给出的数据:

var myArray = [ 
    ['X', 'A', 0, 1, 'Y', 3], 
    ['X', 'A', 4, 5, 'Y', 6], 
    ['X', 'B', 6, 5, 'Y', 4], 
    ['X', 'B', 3, 2, 'Y', 1], 
    ['X', 'C', 7, 8, 'Y', 9], 
]; 

说我想按列索引1只有和列索引2, 3, 5

预期的结果是:

[ 
    ["A", 4, 6, 9], 
    ["B", 9, 7, 5], 
    ["C", 7, 8, 9] 
] 

// data 
 
var myArray = [ 
 
    ['X', 'A', 0, 1, 'Y', 3], 
 
    ['X', 'A', 4, 5, 'Y', 6], 
 
    ['X', 'B', 6, 5, 'Y', 4], 
 
    ['X', 'B', 3, 2, 'Y', 1], 
 
    ['X', 'C', 7, 8, 'Y', 9], 
 
]; 
 

 
// col that I want to group by 
 
var colIndex = 1; 
 

 
// cols I want to sum 
 
var colsToSum = [2, 3, 5]; 
 

 
var arrayGroupBy = function(myArray, colIndex, colsToSum) { 
 

 
    // get unique column values 
 
    var uniqueValues = []; 
 
    myArray.forEach(function(row) { 
 
    if (uniqueValues.indexOf(row[colIndex]) === -1) { 
 
     uniqueValues.push(row[colIndex]); 
 
    } 
 
    }); 
 

 
    var newData = []; 
 
    uniqueValues.forEach(function(value) { 
 

 
    // get filtered rows 
 
    var filteredRows = myArray.filter(function(row) { 
 
     return row[colIndex] === value; 
 
    }); 
 

 
    var row = [value]; 
 

 
    // columns to sum 
 
    colsToSum.forEach(function(num) { 
 
     if (filteredRows.length === 1) { 
 

 
     // push single row 
 
     row.push(filteredRows[0][num]); 
 

 
     } else { 
 

 
     // sum row cols 
 
     var total = filteredRows.reduce(function(sum, current) { 
 
      return sum + current[num]; 
 
     }, 0); 
 

 
     row.push(total); 
 
     } 
 

 
    }); 
 

 
    newData.push(row); 
 
    }); 
 

 
    return newData; 
 
}; 
 

 
console.log(arrayGroupBy(myArray, colIndex, colsToSum));

可惜我不能在这一个使用ES6 ...

谢谢!

回答

0

我试图为您的问题找到解决方案。将有许多优秀的ES6功能,这将使解决方案更易于读取/清洁。但这里是没有任何ES6特征的溶液:

var groupBy = function(myArray, colIndex, colsToSum) { 
    var obj = {}; 
    myArray.forEach(function(e) { 
    if(!obj.hasOwnProperty(e)) { 
     obj[e[colIndex]] = new Array(colsToSum.length + 1) 
     .join('0').split('').map(parseFloat); 
     } 
    }); 

    myArray.forEach(function(row) { 
    for (var i = 0; i < colsToSum.length; i++) { 
     obj[row[colIndex]][i] += row[colsToSum[i]]; 
    } 
    }); 

    return Object.keys(obj).map(function(key) { 
    return [key].concat(obj[key]); 
    }); 
} 

说明:

  • 与属性 'A', 'B' 和 'C' 的对象将被创建。
  • 将为每个属性分配一个数组[0, 0, 0]
  • myArraycolsToSum和值添加到右侧的对象属性
  • 将对象转换为数组,并返回其

也许有更好的解决方案:)

相关问题