2017-04-26 5 views
0

月間のチケット数を合計しようとしています。私が持っている配列:私が欲しいJavaScriptを使用した合計機能

[['tickets', 'month','year'], [1, "june",2016],[3, "june",2015],[1, "december",2015]] 

結果:

[['year', 'june','december'], [2016,1,0],[2015,3,1]] 

が、私はJavaScriptでそれを行う方法を見つけ出すことはできません。 助けてください? ありがとう、

+6

「['年'、 'ジュン'、 'デューク'] 'とはどのようになりますか?何か試しましたか? –

+0

確かに実行可能ですが、このデータを格納するデータ構造(つまりオブジェクト)がはるかに優れています。あなたはあなたの希望の出力で提供されているデータ構造にロックされていますか? – mhodges

+0

@FelixKling配列の最初の要素は基本的にヘッダーです。彼らは他の配列要素のデータと整列しています。 – mhodges

答えて

0
ここ( spread syntaxarray destructuring)を備えていES6のうち、あなたが実際にはかなりクールな使用を得ることができます

アイデアは、あなたの年/ヶ月/総チケットを含むオブジェクトを作成することです

元のデータソースから取得し、そのオブジェクトを使用して、必要な構造にデータをマップすることができます。

var data = [['tickets', 'month', 'year'], [1, "june", 2016], [3, "june", 2015], [1, "december", 2015]]; 
 

 
function mapTicketData(data) { 
 
    var dataMap = data.slice(1).reduce(function(results, current, index) { 
 
    var [tickets, month, year] = current; 
 
    if (results.months.indexOf(month) === -1) { 
 
     results.months.push(month); 
 
    } 
 
    if (results.years.indexOf(year) === -1) { 
 
     results.years.push(year); 
 
    } 
 
    if (!results[year]) { 
 
     results[year] = {}; 
 
    } 
 
    if (!results[year][month]) { 
 
     results[year][month] = 0; 
 
    } 
 
    results[year][month] += tickets; 
 

 
    return results; 
 
    }, { months: [], years: [] }); 
 

 
    return [['year', ...dataMap.months], ...dataMap.years.map(function(year) { 
 
     return [year].concat(dataMap.months.map(function(month) { 
 
     return dataMap[year][month] || 0; 
 
     })); 
 
    }) 
 
    ]; 
 
} 
 

 
console.log(mapTicketData(data));

+0

@mhodgesありがとうございました!それはまさに私が必要としたものです – Jiji

1

私はオブジェクトに日付をグループ化し、エントリを持つ月のユニークな配列を作成し、それからあなたが望む配列に処理しています。

var inArray = [['tickets', 'month','year'], [1, "june",2016],[3, "june",2015],[1, "december",2015]] 
 
var validMonths = {} 
 

 
function dateReducer (acc, curr) { 
 
    var year = curr[2] 
 
    var month = curr[1] 
 
    var num = curr[0] 
 
    if (year === "year"){return acc} 
 
    validMonths[month] = 0 // build unique array of valid months 
 
    
 
    if (!acc[year]) { 
 
    acc[year] = {} 
 
    acc[year][month] = num 
 
    } else { 
 
    if (!acc[year][month]) { 
 
     acc[year][month] = num 
 
    } else { 
 
     acc[year][month] += num 
 
    } 
 
    } 
 
    return acc 
 
} 
 

 
var obj = inArray.reduce(dateReducer, {}) 
 
// This may be fine, depending on your needs 
 
validMonths = Object.keys(validMonths) 
 
var outArray = ["year"].concat(validMonths) 
 

 
for (var year in obj) { 
 
    if (obj.hasOwnProperty(year)){ 
 
    var subArray = [year] 
 
    validMonths.forEach(v => { 
 
     subArray.push(obj[year][v] || 0) 
 
    }) 
 
    outArray.push(subArray) 
 
    } 
 
} 
 

 
console.log(outArray)

+0

OPがそれを必要とするかどうかわかりませんが、この解決策は年の順序を保持しません – mhodges

+0

これは重要な要素であればソートで簡単に実装できます。 –

1

あなたは年を基準として、ハッシュテーブルを持つ月の任意の数のための動的なアプローチを使用することができます。

var data = [['tickets', 'month', 'year'], [1, "june", 2016], [3, "june", 2015], [1, "december", 2015]], 
 
    columns = ['year', 'june', 'december'], 
 
    temp = data.slice(1).reduce(function (result, item) { 
 
     result[item[2]] = result[item[2]] || {}; 
 
     result[item[2]][item[1]] = item[0]; 
 
     return result; 
 
    }, {}), 
 
    result = Object.keys(temp).sort(function (a, b) { return b - a; }).map(function (year) { 
 
     return columns.map(function (month, i) { 
 
      return i ? temp[year][month] || 0 : +year; 
 
     }); 
 
    }); 
 

 
result.unshift(columns); 
 

 
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

+1

なぜ1文字の変数名ですか?これはおそらく、学習し、自分のコードに組み込むことを試みている人のためにできる最悪の最悪の事の一つです。 – mhodges

+1

それはちょうどカウント変数として 'i'のように、配列の項目に' a'を、結果/戻り値に 'r'を選択します。 –

+0

怠け者であり、曖昧で、読みにくく、自己文書化ではありません。異なる文字/略語は、異なる人々と異なることを意味する。それはあなたに意味をなさないかもしれませんが、 'item'の' a'は私には意味がありません。 – mhodges

関連する問題