npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

ts-iterators

v1.0.1

Published

Collection of functions that add array like methods for iterators

Downloads

2

Readme

Test

ts-iterators

Ever been frustrated that you can't sort a Set, or get the first 10 elements in a Map? Well now you can! TS iterators offers a comprehensive collection of functions that operate on any Iterable values, and return Iterables in turn. This includes all the common JS Array methods; such as map, sort, reduce and slice! Some additional ones inspired by Rust, and a few new ones.

Why Iterators?

JS iterators are a very powerful. On a simple level they provide a standardised interface for accessing the element of any type of collections. At a more complex level iterators pull their values from their source, one element at a time. So they do not need to copy the entire contents of the collection. Even more clever is that the source doesn't need to be a collection, it could be a generator which creates a new value each time it pulled upon. This lazy nature means that if you only need to process part of a list, you only have to do the work for those values! Saving processing time and memory.

The hardest part of dealing with iterators in JS is that all the clever helpers for dealing with collections are methods on Arrays. While it's trivial to convert an iterator into an array you lose out on many of the advantages of using an iterator, making it is very wasteful. Hence the creation of this collection. Whereever possible everything is done without collecting up the entries of an iterator, and just works on an element by element basis. Outputs are also iterable values, allowing for easy composition, and of course everything is nicely typed to make it easy to use.

Example

Here is a simple example of composing a source (range), two operators (filter and map) and a consumer (join).

import { range, filter, map, join } from 'ts-iterators';

function isEven (value: number): boolean {
	return (v % 2) === 0;
}

let values: Iterable<number> = range(1, 10);
let even: Iterable<number> = filter(values, isEven);
let inverse: Iterable<string> = map(even, (v: number) => `${v} = ${1 / v}`)

console.log(join(inverse, '\n'))

Common gotcha

import { map } from 'ts-iterators'
map([1, 2, 3], console.log);

At first glance the above code looks perfectly correct. However, it doesn't log anything. Why is that? The answer is that map is an operator, not a consumer. Hence it does not consume it's source when used but rather creates a new source that can be consumed, which in turn consumes it's source. An easy way to consume an iterator is by using the spread operator like so.

import { map } from 'ts-iterators'
const incremented = map([1, 2, 3], v => v + 1);
console.log(...incremented); // 2, 3, 4

It's not uncommon to use Array.map to iterate over a map and then not use the new array it creates, mainly because it's more succinct than Array.forEach. But in the case of iterators the difference is a bit more stark, as the function isn't called unless you use the return value. You can just use forEach instead though:

import { forEach } from 'ts-iterators'
forEach([1, 2, 3], console.log);
// 1
// 2
// 3

Sources

A source creates a new iterable value based on a set of parameters.

  • range
  • entries
  • fromArray
  • fromIterator
  • infinity
  • keys
  • of
  • range
  • repeat

Operators

An operator takes 1 or more iterable values, performs an operation on them and emits 1 or more new iterable values containing the output.

  • buffer
  • chunk
  • concat
  • duplicate
  • fill
  • filter
  • flat
  • flatMap
  • map
  • reverse
  • skip
  • slice
  • sort
  • split
  • unzip
  • zip

Consumers

A consumer takes 1 or more iterable values, consumes their values and emits some form of output.

  • compare
  • every
  • find
  • findIndex
  • first
  • forEach
  • includes
  • indexOf
  • join
  • last
  • lastIndexOf
  • length
  • reduce
  • reduceRight
  • some