2017-02-15 4 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));

残念ながら、私は...この1に

感謝を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とオブジェクトを配列に変換し、それを

を返す権利オブジェクトプロパティ

  • に値を追加たぶん、より良いソリューションがあります:)

  • 関連する問題