2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

好きなIteratorのメソッド発表ドラゴン

Last updated at Posted at 2025-12-29

2025年の5月にIterator HelperがBaselineに乗ったそうです。

Iteratorのことを知ればもっとプログラミングが面白くなるでしょう。
今回はTypeScriptをメインに話を進めますがIteratorの考え方はどの言語でも持ち込めるのでぜひ。
詳しい基本理念を説明しようよ思ったんですが思った以上に難しかったためこの記事は好きなIteratorのメソッド発表ドラゴンさんが執筆致します。

コード自体はTypeScriptで書きますがTypeScriptに限らずいろんな言語のメソッドを想像で書きます。

map (Iterator<I> -> fn(i: I): O -> Iterator<O>)

王道の王道です。
アイテムを一つ一つ変換していきます。

const lines = [ "1,taro", "2,hanako", "3,neko" ];
const data = lines[Symbol.iterator]()
  .map((line) => line.split(","))
  .map(([id, name]) => ({
    id,
    name
  }));
console.log(data); // [ { id: '1', name: 'taro' }, { id: '2', name: 'hanako' }, { id: '3', name: 'neko' } ]

filter (Iterator<I> -> fn(i: I): boolean -> Iterator<I>)

条件に一致するアイテムだけを通します。

const numbers = [ 1, 2, 3, 4, 5 ];
const evens = numbers[Symbol.iterator]()
  .filter((n) => n % 2 === 0);

console.log(evens); // [ 2, 4 ]

flat (Iterator<Iterable<I>> -> Iterator<I>)

入れ子になっているIterableを展開します。

const boxes = [ ["1", "2"], ["3"], ["4", "5"] ];

// 箱から中身をぶちまけて一列にする
const fruits = boxes[Symbol.iterator]()
  .flat();

console.log(fruits); // [ "1", "2", "3", "4", "5" ]

find (Iterator<I> -> fn(i: I): boolean -> I | undefined)

条件に一致するIを1 or 0こ返します。
ID検索をするときとかに有用です。
条件に一致しない可能性もあるため、I | undefined

const users = [
  { id: 1, name: 'taro' },
  { id: 2, name: 'hanako' },
  { id: 3, name: 'neko' }
];

const target = users[Symbol.iterator]()
  .find((user) => user.id === 2);

console.log(target); // { id: 2, name: 'hanako' }

reduce (Iterator<I> -> fn(acc: A, cur: I): A -> A)

一つの結果にまとめるやつ

const prices = [ 100, 200, 300 ];
const total = prices[Symbol.iterator]()
  .reduce((acc, price) => acc + price, 0);

console.log(total); // 600

every (Iterator<I> -> fn(i: I): boolean -> boolean)

一つでも要素を調べていく過程でfnfalseを返せばfalseを変えます。

// 全てが80以上だと
const scores = [ 80, 95, 100 ];
const isAllPassed = scores[Symbol.iterator]()
  .every((score) => score >= 80);

console.log(isAllPassed); // true

// 80未満が一つでもあると、、、
const scores = [ 70, 95, 100 ];
const isAllPassed = scores[Symbol.iterator]()
  .every((score) => score >= 80);

console.log(isAllPassed); // false

some (Iterator<I> -> fn(i: I): boolean -> boolean)

fnが一つでもtrueを返すとそこで探索をやめ、trueを返します。

// 一つでも80以上があると
const scores = [ 90, 2, 10 ];
const isSomePassed = scores[Symbol.iterator]()
  .some((score) => score >= 80);

console.log(isSomePassed); // true

// 80以上が一つもないと
const scores = [ 70, 2, 12 ];
const isSomePassed = scores[Symbol.iterator]()
  .some((score) => score >= 80);

console.log(isSomePassed); // false

zip (Iterator<A> -> Iterable<B> -> Iterator<[A, B]>)

データの順序は保証されているがそれぞれ別の配列にデータが有るとき。

お互いのiteratorが一致しない場合長いの方のはみ出し分はカットされる。

const headers = [ "id", "name", "role" ];
const values = [ 1, "taro", "admin", "extra" ];

const entries = headers[Symbol.iterator]()
  .zip(values[Symbol.iterator]());

console.log(entries); // [ ["id", 1], ["name", "taro"], ["role", "admin"] ]

take (Iterator<I> -> count: number -> Iterator<I>)

指定した数の分だけ先頭から取ってくる。
n個指定したからといって、必ずn個来る保証は無い。

const ranking = [ "1位", "2位", "3位", "4位", "5位" ];
const top3 = ranking[Symbol.iterator]()
  .take(3);

console.log(top3); // [ "1位", "2位", "3位" ]

drop (Iterator<I> -> count: number -> Iterator<I>)

takeの逆です。
n個進めたあとのIteratorを返してくれます。

const ranking = [ "1位", "2位", "3位", "4位", "5位" ];
const outTop3 = ranking[Symbol.iterator]()
  .drop(3);

console.log(outTop3); // [ "4位", "5位" ]

終わりに

私が使ったことのあるメソッドたちを書いて見ました。
今回はTypeScriptで説明をしましたが、Iteratorを好きになったきっかけはRustを触ったことでした。

RustのIteratorには多種多様なnextを応用したメソッドがあり好奇心かき立たされると同時に、TypeScriptのIteratorの不十分さで少し残念な気持ちになっていました。

しかし、記事冒頭にも書いた通りただのInterfaceからIterator Helperとして機能が増えており非常に嬉しかったです。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?