ワンライナーで行こう!(JavaScriptで配列操作いろいろ)

ワンライナーで行こう!(JavaScriptで配列操作いろいろ):


ワンライナーとは

はてなキーワードによると、

「ワンライナー」とは、たった1行だけのプログラムです。PerlやRubyを使うと、1行だけでもかなりの仕事ができます。 プログラムを書きたいが、エディタを起動するほどの手間はかけたくない、というときに威力を発揮します。達人ともなると、ちょっとした文字置換や計算をするワンライナーを、即興で作って使い捨てることもあります。PerlやRubyは、ワンライナーを書くために役立つオプションを豊富に持っています。
Javascriptでも、ES2015以降、アロー演算子や、Array.prototype.filterやArray.prototype.map等の関数でワンライナーが作りやすくなりました。配列操作系を中心に、便利なワンライナー集を作ってみました!

※ネタが思い付き次第順次追加していきたいと思います。「もっと短くできる!」「イクナイ」等のご指摘や、他のワンライナーネタがありましたら、コメント欄にお願いします。


startからendまでの連続した数値配列を生成する

start=1, end=10の配列(公差1の等差数列)を生成

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); 
 
// 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重括弧状態を解除 

コメント

このブログの人気の投稿

投稿時間:2021-06-17 22:08:45 RSSフィード2021-06-17 22:00 分まとめ(2089件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)