prefer-specific-methodlisted
Install: claude install-skill ncaq/konoka
# より特化した関数を優先する
同じ結果が得られる方法が複数ある場合は、
やりたいことに最も特化した関数を選んでください。
特化した関数は名前そのものが意図を表すので、
読み手が「この比較は何のためか」を推測せずに済みます。
汎用的な関数を条件式と組み合わせて目的を表現すると、
意図が式の形に埋もれて読みにくくなります。
これは[avoid-for](../avoid-for/SKILL.md)で`for`を高抽象度の関数に置き換えるのと同じ発想を、
関数同士の選択にも広げたものです。
## 存在するかどうかを調べる
要素が含まれるかを知りたいだけなら、
位置を返す`indexOf`ではなく、
真偽値を返す`includes`を使います。
```typescript
// 避ける
if (items.indexOf(target) !== -1) {
}
// 良い
if (items.includes(target)) {
}
```
`includes`は意図が明確なだけでなく、
`NaN`を正しく見つけられるという正確性の利点もあります。
`indexOf`は厳密等価(`===`)で比較するため`NaN`を見つけられませんが、
`includes`はSameValueZeroで比較するため`NaN`も見つけられます。
```typescript
[NaN].indexOf(NaN); // -1 (見つからない)
[NaN].includes(NaN); // true
```
## 条件を満たす要素の有無を調べる
絞り込んだ結果の件数を見るのではなく、
`some`や`every`で真偽を直接求めます。
```typescript
// 避ける
if (0 < users.filter((user) => user.active).length) {
}
// 良い
if (users.some((user) => user.active)) {
}
```
`some`は最初に条件を満たした時点で打ち切るので、
全件を絞り込む`filter`より無駄がありません。
「すべてが条件を満たすか」は`every`を使います。
## 条件を満たす最初の要素を取り出す
絞り込んでから先頭を取るのではなく、
`find`で直接取り出します。
```typescript
// 避ける
const found = users.filter((user) => user.id === targetId)[0];
// 良い
const found = users.find((user) => user.id === targetId);
```
最後の要素が欲しい場合は`findLast`、
位置が欲しい場合は`findIndex`や`findLastIndex`を使います。
## 変換してから平坦化する
`map`してから`flat`するのではなく、
`flatMap`を使います。
```typescript
// 避ける
const tags = posts.map((post) => post.tags).flat();
// 良い
const tags = posts.flatMap((post) => post.tags);
```
## 末尾や負の位置の要素にアクセスする
`length`を使った添字計算ではなく、
`at`を使います。
```typescript
// 避ける
const