JavaScriptの1行小ネタ集

動作要件：ES6以上

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

```javascript
Array(n).fill(0)
```

例

```javascript
Array(5).fill(0) //[0, 0, 0, 0, 0]
```

##### 長さnで要素がランダムな一次元配列
```javascript
Array(n).fill().map(v => Math.random())
```

例

```javascript
Array(3).fill().map(v => Math.random())
//[0.6330667476794745, 0.037943580782855424, 0.02379933999044881]
```

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

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

例

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

##### 配列のsum

```javascript
arr.reduce((a, b) => a + b)
```

##### 配列の総乗

```javascript
arr.reduce((a, b) => a * b)
```

##### 配列の平均

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

##### 配列のmax/min

```javascript
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

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

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

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

```javascript
arr.filter(v => v === 'value').length
```

例

```javascript
const arr = ['A', 'B', 'C', 'B', 'B', 'A'];
arr.filter(v => v === 'A').length //2
```

応用：Pythonの`collections.Counter`

```javascript
const counter = arr => arr.reduce((a, b) => ({...a, [b] : (a[b] ?? 0) + 1 }) , {});
```

例

```javascript
const arr = ['A', 'B', 'C', 'B', 'B', 'A'];
counter(arr); //{ A: 2, B: 3, C: 1 }
```

##### 配列の重複消去

```javascript
[...new Set(arr)]
```

例

```javascript
const arr = ['A', 'B', 'C', 'B', 'B', 'A'];
[...new Set(arr)] //["A", "B", "C"]
```

##### 二点間の距離

```javascript
Math.hypot(x1 - x0, y1 - y0)
```

##### UUID生成

```javascript
([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
Chrome 92以降なら

```javascript
crypto.randomUUID()
```

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

```javascript
arr.includes('value')
```

##### 階乗を返す関数

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

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

##### 小数点以下切り捨て/四捨五入

```javascript
~~1.5 //1(切り捨て)
~~(1.5 + 0.5) //2(四捨五入)
```

又は

```javascript
1.5 | 0 //1(切り捨て)
1.5 + 0.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.round()`を使う

```javascript
Math.trunc(1.5) //1(切り捨て)
Math.round(1.5) //2(四捨五入)
```

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

```javascript
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)

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

##### fetch

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

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

```javascript
str.startsWith('Hi') //Boolean
```

第二引数に数字を与えれば、そこを支点に判定する
終わりから探索したいときはendsWith

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

```javascript
arr.every(v => 条件) //Boolean
```

例

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

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

```javascript
[...document.querySelectorAll('')].filter(v => 条件)
```

(文字列にも使える)
※forEachはスプレッド演算子`...`で展開する必要なし

##### 配列の次元を1下げる
```javascript
[].concat(...arr)
```
ES2019以上ならば

```javascript
arr.flat()
```

例

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

##### 一次元配列を二次元に変換

```javascript
arr.reduce((a, v, i) => i % len ? a : [...a, arr.slice(i, i + len)] , [])
```
lenは要素数

例

```javascript
let arr = [1, 2, 3, 4, 5, 6];
const len = 2;
arr = arr.reduce((a, v, i) => i % len ? a : [...a, arr.slice(i, i + len)] , []);
console.log(arr); //[[1, 2], [3, 4], [5, 6]]
```

##### findIndexAll

```javascript
arr.reduce((a, v, i) => v === '条件' ? [...a, i] : a, [])
```

例

```javascript
['a', 'b', 'a'].reduce((a, v, i) => v === 'a' ? [...a, i] : a, [])
//[0, 2]
```

##### オブジェクトを配列に変換
```javascript
Object.keys(obj).map(v => [v, obj[v]])
```

ES2017以上ならば

```javascript
Object.entries(obj)
```

##### Mapオブジェクトをオブジェクトに変換
```javascript
[...mapObj].reduce((obj, [k, v]) => ({ ...obj, [k]: v }), {})
```

ES2019以上ならば

```javascript
Object.fromEntries([...mapObj])
```

例

```javascript
Object.fromEntries([...new Map([['a', 1], ['b', 2]])])
//{a: 1, b: 2}
```

##### consoleのメソッドを無効化
```javascript
for (const method in console) console[method] = () => {};
```

##### 配列の和集合
```javascript
[...new Set([...arr1, ...arr2])]
```

##### 配列の積集合
```javascript
arr1.filter(v => arr2.includes(v))
```

##### 配列の差集合
```javascript
arr1.filter(v => !(arr2.includes(v)))
```

##### number[]ソート
```javascript
arr.sort((a, b) => a - b)
```

例

```javascript
[2, 3, 1, 10].sort((a, b) => a - b); // [1, 2, 3, 10]
```

#### string[]ソート
```javascript
arr.sort()
```

例

```javascript
['b', 'c', 'a'].sort(); // ["a", "b", "c"]
```

#### オブジェクトのプロパティ(number)でソート
```javascript
arr.sort(({ prop : a }, { prop : b }) => a - b)
```
例

```javascript
[{ v: 2 }, { v: 3 }, { v: 1 }, { v: 10 }].sort(({ v: a }, { v: b }) => a - b);
// [{ v: 1 }, { v: 2 }, { v: 3 }, { v: 10 }];
```

#### オブジェクトのプロパティ(string)でソート
```javascript
arr.sort(({ prop : a }, { prop : b }) => a < b ? -1 : b < a ? 1 : 0)
```
例

```javascript
[{ v: 'b' }, { v: 'a' }, { v: 'c' }].sort(({ v: a }, { v: b }) =>
  a < b ? -1 : b < a ? 1 : 0
);
// [{ v: 'a' }, { v: 'b' }, { v: 'c' }];
```