背景
JavaScriptでcsvのデータを処理していて, 2次元配列を一つにつなげて1次元配列にしたかった.
問題
こんなデータをどやって1次元配列に格納するか.
const data = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12],
];
対処法
方法1: 古典的にfor文を回して, pushする
まず, 空の配列を用意して, 2重のfor文を回して順次pushしていく方法
var list = [];
for(var i=0;i<data.length;i=i+1){
for(var j=0;j<data[i].length;j=j+1){
list.push(data[i][j]);
}
}
方法2: 今風(ES2015)な方法 reduce と スプレッド演算子
reduceとスプレッド演算子(...のこと)を使うと一行で代入できる.
const list = data.reduce((pre,current) => {pre.push(...current);return pre},[]);
実行速度
では実行速度はどうなのだろうか.
今風な書き方の方が短く書けるから好きだけれど, 古典的for文の方が早いと思っていた.
しかし, 結果は違った.
Chrom ver. 64.0.3282.140
でconsole.time()とconsole.timeEnd()を使て計測した.
1000×1000の2次元データの1次元への変換を100回繰り返すのにかかった時間が下記
方法1: for文 | 方法2: reduce+スプレッド演算子 |
---|---|
2331 ms | 1784 ms |
なんと今風な方法2の方が速い!!
テスト方法
jsnoteにテストコードを張り付けて実行した.
jsnoteについてはこちらの記事
テストコード
speedTest.js
const data = [];
for(let i=0;i<1000;i++){
data[i]=[];
for(let j=0;j<1000;j++){
data[i][j]=i*10+j;
}
}
console.log(origin);
console.time("method1");
for(var n=0;n<100;n++){
var list = [];
for(var i=0;i<data.length;i=i+1){
for(var j=0;j<data[i].length;j=j+1){
list.push(data[i][j]);
}
}
}
console.timeEnd("method1");
console.time("method2");
for(let n=0;n<100;n++){
const list = data.reduce((pre,current) => {pre.push(...current);return pre},[]);
}
console.timeEnd("method2");
感想
これからは心置きなく今風なやり方でどんどん行こう.