diff --git a/builtin/builtin.mbti b/builtin/builtin.mbti index f02d3c54f..5a6759c75 100644 --- a/builtin/builtin.mbti +++ b/builtin/builtin.mbti @@ -236,6 +236,8 @@ impl Iter { head[A](Self[A]) -> A? intersperse[A](Self[A], A) -> Self[A] iter[T](Self[T]) -> Self[T] + iter2[K, V](Self[(K, V)]) -> Iter2[K, V] + iteri[T](Self[T], offset~ : Int = ..) -> Iter2[Int, T] join(Self[String], String) -> String just_run[T](Self[T], (T) -> IterResult) -> Unit last[A](Self[A]) -> A? diff --git a/builtin/iter.mbt b/builtin/iter.mbt index b8cad980b..c2aa57c68 100644 --- a/builtin/iter.mbt +++ b/builtin/iter.mbt @@ -968,3 +968,23 @@ pub fn Iter::minimum[T : Compare](self : Iter[T]) -> T? { } res } + +///| +/// Returns an iterator that iterates over the index and the element of the iterator. +pub fn Iter::iteri[T](self : Iter[T], offset~ : Int = 0) -> Iter2[Int, T] { + fn { + yield_ => { + let mut value = offset - 1 + self.run(fn(i) { + value += 1 + yield_(value, i) + }) + } + } +} + +///| +/// Returns an iterator that iterates over the key value pair. +pub fn Iter::iter2[K, V](self : Iter[(K, V)]) -> Iter2[K, V] { + fn { yield_ => self.run(fn { (k, v) => yield_(k, v) }) } +} diff --git a/builtin/iter_test.mbt b/builtin/iter_test.mbt index f55a312da..53408c239 100644 --- a/builtin/iter_test.mbt +++ b/builtin/iter_test.mbt @@ -748,3 +748,31 @@ test "Float::until negative step" { let result = 10.0.until(0.0, step=-2.0).collect() inspect!(result, content="[10, 8, 6, 4, 2]") } + +///| +test "iteri" { + let iter = [].iter() + for _, _ in iter.iteri() { + assert_true!(false) + } + let iter = [0, 1, 2].iter() + for i, x in iter.iteri() { + assert_eq!(i, x) + } + let iter = [0, 1, 2].iter() + for i, x in iter.iteri(offset=10) { + assert_eq!(i, x + 10) + } +} + +///| +test "iter2" { + let iter = [].iter() + for _, _ in iter.iter2() { + assert_true!(false) + } + let iter = [(0, 1), (2, 3), (4, 5)].iter() + for k, v in iter.iter2() { + assert_eq!(k + 1, v) + } +}