tohokuaikiのチラシの裏

技術的ネタとか。

TypeScriptでデータを元に重複を見てループする方法

俺のコード

type Job = Record<'area' | 'act' | 'type' | 'num' | 'days' | 'limit', string>;
type Filter = Record<'area' | 'act' | 'type', string[]>;

const filter:Filter = { area: [], act: [], type: [] };
(async () => {
    const resp = await fetch('https://exmple.com/api/jobs');
    const jobs = await resp.json() as Job[];
     jobs.map((job) => {
         if (filter.area.indexOf(job.area) < 0) filter.area.push(job.area);
         if (filter.act.indexOf(job.act) < 0) filter.act.push(job.act);
         if (filter.type.indexOf(job.type) < 0) filter.type.push(job.type);
    });
})();

ChatGPTに質問

このTypeScriptをもっと行数を少なく書けますか?特にmapのループが短くなれるとよいです。

ChatGPTの回答

改善点:

  • filterオブジェクトに対するpush処理は重複チェックを省略してシンプルにできます。
  • mapを使用するのではなく、forEachを使用して直接filterに値を追加できます。
  • indexOfの代わりにSetを使うと、重複のチェックと追加が高速で簡潔になります。

以下は改善後のコードです:

type Job = Record<'area' | 'act' | 'type' | 'num' | 'days' | 'limit', string>;
type Filter = Record<'area' | 'act' | 'type', Set<string>>;

const filter: Filter = { area: new Set(), act: new Set(), type: new Set() };

(async () => {
    const resp = await fetch('https://exmple.com/api/jobs');
    const jobs = await resp.json() as Job[];

    jobs.forEach((job) => {
        filter.area.add(job.area);
        filter.act.add(job.act);
        filter.type.add(job.type);
    });
})();

改善のポイント:

この方法で、より効率的で簡潔なコードを実現できます。

Setを使用:

Setを使うことで、重複チェックが簡単になります。Setは自動的に重複を排除するため、indexOfを使って手動でチェックする必要がありません。 add()メソッドで要素を追加するだけで、重複が自動的に排除されます。

forEachを使用:

mapは配列を新しく返すため、返り値を使わない場合はforEachが適切です。mapの返り値を無視する場合、forEachで直接処理する方が簡潔です。