Edited at

JavaScriptの1行小ネタ集

動作要件:ES6以上


長さnですべての要素が0の一次元配列

Array(n).fill(0);

Array(5).fill(0); //[0, 0, 0, 0, 0]


長さnで要素がランダムな一次元配列

Array(n).fill().map(v => Math.random());

Array(3).fill().map(v => Math.random());

//[0.6330667476794745, 0.037943580782855424, 0.02379933999044881]


0からn-1まで公差1の等差数列

[...Array(n).keys()]

[...Array(5).keys()]; //[0, 1, 2, 3, 4]


配列のsum

arr.reduce((a, b) => a + b);


配列の総乗

arr.reduce((a, b) => a * b);


配列の平均

arr.reduce((a, b) => a + b) / arr.length;


配列のmax/min

Math.max(...arr);

※引数の上限数を超える長さの配列では、うまく動作しない可能性があります。

環境
引数の上限

Chrome 68.0.3550.0
65535

Node.js 8.12.0
65535

IE 11.285.17134.0
131071

Edge 42.17134.1.0
262143

Firefox 62.0.3
262143

Windows 10 64bitで検証

検証コード:https://stackoverflow.com/questions/22747068/is-there-a-max-number-of-arguments-javascript-functions-can-accept#answer-22747272

そのため、以下のコードの方が上限が無く安全です。

arr.reduce((a, b) => Math.max(a, b))


配列内で出てくる回数を数える

arr.filter(v => v === 'value').length;

const arr = ['A', 'B', 'C', 'B', 'B', 'A'];

arr.filter(v => v === 'A').length; //2

応用:Pythonのcollections.Counter(ES2019以上)

const Counter = arr => Object.fromEntries([...new Set(arr)].map(v1 => ([v1, arr.filter(v2 => v2 === v1).length])));

const arr = ['A', 'B', 'C', 'B', 'B', 'A'];

Counter(arr); //{ A: 2, B: 3, C: 1 }


配列の重複消去

[...new Set(arr)];

const arr = ['A', 'B', 'C', 'B', 'B', 'A'];

[...new Set(arr)]; //["A", "B", "C"]


二点間の距離

Math.hypot(x1 - x0, y1 - y0);


UUID生成

([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16));

ここまでの参考元:https://github.com/Chalarangelo/30-seconds-of-code


配列(または文字列)に含まれるかどうか(bool)

arr.includes('value');

indexOfより短い

if(str.indexOf('value') !== -1)

if(!str.includes('value'))


階乗を返す関数

const f = n => n == 0 && 1 || n * f(n - 1);

参考元:http://www.jstips.co/en/javascript/recursion-iteration-and-tail-calls-in-js/


小数点以下切り捨て

~~1.5 //1

~~(1 + 1.5) //2

又は

1.5 | 0 //1

1 + 1.5 | 0 //2

※どちらも32bit int範囲内(-2,147,483,647~2,147,483,647)でしかうまく動作しません。

詳細:https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators

32bit int範囲外も扱う場合はMath.trunc()を使う

Math.trunc(2147483647 + 1); //2147483648


配列の順番をランダムに混ぜる関数(Fisher Yates shuffle)

const shuffle = e => [...e.keys()].map(v => v + (e.length - v) * Math.random() | 0).forEach((v, i) => [e[i], e[v]] = [e[v], e[i]]) || e;

※実行速度が普通に書いたものより2倍程度遅いです...


順番をランダムに混ぜた配列を返す関数(random order)

const shuffle = arr => arr.map(v => [Math.random(), v]).sort(([a], [b]) => a - b).map(v => v[1]);


fetch

(async () => await (await fetch('http://example.com')).text())();


特定の文字列で始まるか判定

str.startsWith('Hi'); //bool

第二引数に数字を与えれば、そこを支点に判定する

終わりから探索したいときはendsWith


配列のすべての値が条件をみたすかどうか

arr.every(v => 条件); //bool

[1, 2, 3, 4].every(v => v > 0); //true


document.querySelectorAll()でfilter/mapなどをする

[...document.querySelectorAll('')].filter(v => );

(文字列にも使える)

※forEachはスプレッド演算子...で展開する必要なし


配列の次元を1下げる

[].concat(...arr);

ES2019以上ならば

arr.flat();

[1, [2, 3]].flat(); //[1, 2, 3]


一次元配列を二次元に変換(nは行の長さ)

while(arr.length) newArr.push(arr.splice(0, n));

const arr = [1, 2, 3, 4, 5, 6];

const newArr = [];
while(arr.length) newArr.push(arr.splice(0, 3));
console.log(newArr); //[[1, 2, 3], [4, 5, 6]]

元ネタ:https://stackoverflow.com/questions/22464605/convert-a-1d-array-to-2d-array/


オブジェクトを配列に変換

Object.keys(obj).map(v => [v, obj[v]]);

ES2017以上ならば

Object.entries(obj);


Mapオブジェクトをオブジェクトに変換

[...mapObj].reduce((obj, [k, v]) => ({ ...obj, [k]: v }), {});

ES2019以上ならば

Object.fromEntries([...mapObj]);

Object.fromEntries([...new Map([['a', 1], ['b', 2]])]);

//{a: 1, b: 2}


consoleのメソッドを無効化

for (const method in console) console[method] = () => {};


配列の和集合

[...new Set([...arr1, ...arr2])]


配列の積集合

arr1.filter(v => arr2.includes(v));


配列の差集合

arr1.filter(v => !(arr2.includes(v)));