Edited at

JavaScriptで2次元配列を1次元配列に変換する今風なやり方 reduce + スプレッド演算子(...) しかも速い!!

More than 1 year has passed since last update.


背景

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にテストコードを張り付けて実行した.

Imgur

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");



感想

これからは心置きなく今風なやり方でどんどん行こう.