##ワンライナーとは
はてなキーワードによると、
「ワンライナー」とは、たった1行だけのプログラムです。PerlやRubyを使うと、1行だけでもかなりの仕事ができます。 プログラムを書きたいが、エディタを起動するほどの手間はかけたくない、というときに威力を発揮します。達人ともなると、ちょっとした文字置換や計算をするワンライナーを、即興で作って使い捨てることもあります。PerlやRubyは、ワンライナーを書くために役立つオプションを豊富に持っています。
Javascriptでも、ES2015以降、アロー演算子や、Array.prototype.filterやArray.prototype.map等の関数でワンライナーが作りやすくなりました。配列操作系を中心に、便利なワンライナー集を作ってみました!
※ネタが思い付き次第順次追加していきたいと思います。「もっと短くできる!」「イクナイ」等のご指摘や、他のワンライナーネタがありましたら、コメント欄にお願いします。
##startからendまでの連続した数値配列を生成する
start=1, end=10の配列(公差1の等差数列)を生成
var array = Array(end-start+1).fill().map((e,i) => start+i);
//または
var array = Array.apply(0,new Array(end-start+1)).map((e,i) => start+i);
//console.log(array) --> [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
##特定の値の要素を入れ替える
before = 10 から after = 1 へ置換
array = array.map(e => e===before ? after : e);
//console.log(array) --> [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 1 ]
##特定の値の要素を削除する
target = 9 を削除
array = array.filter(e => e!==target);
//console.log(array) --> [ 1, 2, 3, 4, 5, 6, 7, 8, 1 ]
##配列を降順に並び替える
昇順の場合は(a,b)=>a-b。破壊的メソッドのため、=演算子での上書き不要。
array.sort((a,b)=>b-a);
//console.log(array)--> [ 8, 7, 6, 5, 4, 3, 2, 1, 1 ]
##配列を逆順に並び替える
Array.prototype.reverse()そのまま。破壊的メソッドのため、=演算子での上書き不要。
array.reverse();
//console.log(array) --> [ 1, 1, 2, 3, 4, 5, 6, 7, 8 ]
##配列から重複する値を削除する
array = array.filter((e,i,s) => i===s.indexOf(e));
//console.log(array) --> [ 1, 2, 3, 4, 5, 6, 7, 8 ]
##2つの配列を結合する
array = array.concat(array);
//または
array = [...array,...array];
// console.log(array) --> [ 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 ]
##配列から重複する値のみ残す
array = array.filter((e,i,s) => s.indexOf(e)!==s.lastIndexOf(e));
// console.log(array) --> [ 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 ]
##配列から重複する値のみ残した後、重複削除
array = array.filter((e,i,s) => i!==s.indexOf(e));
// console.log(array) --> [ 1, 2, 3, 4, 5, 6, 7, 8 ]
##配列の中身を結合した文字列を作る
var string = array.join().replace(/,/g,"");
// console.log(string) --> 12345678
##数値文字列を分割して数値配列にする
map(e => +e)で数値形式の文字列から数値に変換するのがミソ。
array = string.split('').map(e => +e);
//または
array = Array.from(string).map(e => +e);
// console.log(array) --> [ 1, 2, 3, 4, 5, 6, 7, 8 ]
##配列中の数値の合計値を得る
var sum = array.reduce((a,b) => a+b);
// console.log(sum) --> 36
##配列中の数値の最大値を得る
var max = array.reduce((a,b) => a<b ? b : a);
//または
var max = Math.max.apply(null, array);
//または
var max = Math.max(...array);
// console.log(max) --> 8
##隣り合うN個の要素をまとめた配列の配列を作る(N=3)
filter(e => e.length===3)で、要素数が3に満たない配列[7,8]を落としている
var v = array.map((e,i,s) => i%3===0 ? s.slice(i,i+3) : null).filter(e => e!==null && e.length===3);
// console.log(v) --> [[ 1, 2, 3 ], [ 4, 5, 6 ] ]
##3次元ベクトルの内積
上で作成した2つのベクトル v=[[ 1, 2, 3 ], [ 4, 5, 6 ] ]を使う
var ip = v[0].map((e,i) => v[0][i]*v[1][i]).reduce((a,b) => a+b);
// console.log(ip) --> 32
##3次元ベクトルの外積
内積と同様、v=[[ 1, 2, 3 ], [ 4, 5, 6 ] ]を使う
var op = v[0].map((e,i) => v[0][(i+1)%3]*v[1][(i+2)%3]-v[0][(i+2)%3]*v[1][(i+1)%3]);
// console.log(op) --> [ -3, 6, -3 ]
##隣り合う2要素をまとめた配列の配列を作る(N=2)
N=3の場合をN=2にしただけ
var m = array.map((e,i,s) => i%2===0 ? s.slice(i,i+2) : null).filter(e => e!==null && e.length===2);
// console.log(m) --> [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ], [ 7, 8 ] ]
##マークル木演算
だいぶ苦しくなってきた。ツーライナーに見えるのは気のせいです…
ブランチのペアは上記の m= [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ], [ 7, 8 ] ]を使用。ここでは任意のハッシュ関数をhash()としています。
var i=~~Math.pow(m.length,1/2);while(i>0){m=m.map((e,i,s)=>i%2===0?[hash(e),hash(s[i+1])]:null).filter(e=>e!==null); i=+(i-1);}
マークルツリーアルゴリズムについての解説はこちらを参照しました。
本来、ブランチは文字列で、ループの前に1度ハッシュ関数を通す等の前処理が必要ですが、とりあえず主要部分のみ。
hash()を単なる2要素の足し算にして検算した結果↓(実際に使う場合はSHA256等のハッシュ関数に置き換える)
const hash = (a) => a[0]+a[1];
// console.log(...m) --> [ 10, 26 ] //スプレッド演算子で2重括弧状態を解除