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 🙏

© 2024 – Pkg Stats / Ryan Hefner

jsiq

v0.3.0

Published

Dotnet LINQ inspired query methods for iterators

Downloads

3

Readme

JS Iterator Queries

Inspired by dotnet LINQ I decided to adopt it to use with ES6 iterators.

Usage

Embedding

All methods are implemented as pure functions. And you can always use then as is.

But for convenience and more readable code jsiq provides ability to embed methods to native JS iterable classes: Array, Set, Map. After calling the embed method, you can start call jsiq methods right from your collections:

require('jsiq/lib/embed')();
const personsArray = await loadPersonsAsync();
const underageIterator = personsArray.where(p => p.age < 18);

Chaining

All methods can be chained to build complex queries on your collections:

require('jsiq/lib/embed')();
const personsArray = await loadPersonsAsync();
const reportItems = personsArray
    .where(p => p.age > 18)
    .where(p => p.children && p.children.length > 0)
    .select(p => ({
        name: p.name,
        childrenCount: p.children ? p.children.length : 0,
        isMarried: !!(p.wife || p.husband)
    }))
    .orderBy(p => p.childrenCount)
    .toArray();

Basic usage

And you still can use all methods directly by passing iterators:

const { where, toArray } = require('jsiq');
const personsMap = getPersonsMap();
const underage = toArray(where(personsMap.values(), p => p.age < 18));

Methods

where

Filters a sequence of values based on a predicate. Each element's index is used in the logic of the predicate function.

Signature:

where<T>(
    source: Iterator<T> | Iterable<T>,
    predicate: (item: T, index: Number) => boolean
) => IterableIterator<T>

Basic example:

const adultsQuery = where(personsArray, p => p.age > 18);

Embedded example:

const adultsQuery = personsArray.where(p => p.age > 18);

select

Projects each element of a sequence into a new form.

Signature:

select<T, TResult>(
    source: Iterator<T> | Iterable<T>,
    predicate: (item: T) => TResult
) => IterableIterator<TResult>

Basic example:

const idsQuery = select(personsArray, p => p.id);

Embedded example:

const idsQuery = personsArray.select(p => p.id);

concat

Concatenates two sequences.

Signature:

concat<T>(
    source: Iterator<T> | Iterable<T>,
    appendix: Iterator<T> | Iterable<T>
) => IterableIterator<T>

Basic example:

const personsQuery = concat(childrenQuery, adultsQuery);

Embedded example:

const personsQuery = childrenQuery.concat(adultsQuery);

distinct

Returns distinct elements from a sequence.

Signatures:

distinct<T>(
    source: Iterator<T>
) => IterableIterator<T>

distinct<T, TValue>(
    source: Iterator<T> | Iterable<TSource>,
    selector: (item: T) => TValue
) => IterableIterator<T>

Basic example:

const studentsQuery = distinct(studentsFromGroups);
const personsWithUniqueName = distinct(persons, p => p.name);

Embedded example:

const studentsQuery = studentsFromGroups.distinct();
const personsWithUniqueName = persons.distinct(p => p.name);

take

Returns a specified number of contiguous elements from the start of a sequence.

Signature:

take<T>(
    source: Iterator<T> | Iterable<T>,
    count: number
) => IterableIterator<T>

Basic example:

const first2 = take(personsArray, 2);

Embedded example:

const first2 = personsArray.take(2);

takeWhile

Returns elements from a sequence as long as a specified condition is true. The element's index is used in the logic of the predicate function.

Signature:

takeWhile<T>(
    source: Iterator<T> | Iterable<T>,
    predicate: (item: T, index: Number) => boolean
) => IterableIterator<T>

Basic example:

const untilFirstFail = takeWhile(attempts, at => at.success);

Embedded example:

const untilFirstFail = attempts.takeWhile(at => at.success);

skip

Bypasses a specified number of elements in a sequence and then returns the remaining elements

Signature:

skip<T>(
    source: Iterator<T> | Iterable<T>,
    count: number
) => IterableIterator<T>

Basic example:

const excludeFirst2 = skip(personsArray, 2);

Embedded example:

const excludeFirst2 = personsArray.skip(2);

skipWhile

Bypasses elements in a sequence as long as a specified condition is true and then returns the remaining elements. The element's index is used in the logic of the predicate function.

Signature:

skipWhile<T>(
    source: Iterator<T> | Iterable<T>,
    predicate: (item: T, index: Number) => boolean
) => IterableIterator<T>

Basic example:

const afterFirstFail = skipWhile(attempts, at => at.success);

Embedded example:

const afterFirstFail = attempts.skipWhile(at => at.success);

aggregate

Applies an accumulator function over a sequence. The specified seed value is used as the initial accumulator value, and the specified function is used to select the result value.

Signatures:

aggregate<TSource>(
    source: Iterator<TSource> | Iterable<TSource>,
    fn: (acc: TSource, item: TSource) => TSource
) => TSource;

aggregate<TSource, TResult>(
    source: Iterator<TSource> | Iterable<TSource>,
    fn: (acc: TSource, item: TSource) => TSource,
    resultSelector: (acc: TSource) => TResult
) => TResult;

aggregate<TSource, TAccumulate>(
    source: Iterator<TSource> | Iterable<TSource>,
    seed: TAccumulate,
    fn: (acc: TAccumulate, item: TSource) => TAccumulate
) => TAccumulate;

aggregate<TSource, TAccumulate, TResult>(
    source: Iterator<TSource> | Iterable<TSource>,
    seed: TAccumulate,
    fn: (acc: TAccumulate, item: TSource) => TAccumulate,
    resultSelector: (acc: TAccumulate) => TResult
) => TResult;

Basic example:

const sum = aggregate(integers, (sum, i) => sum + i);

const sumSquare = aggregate(integers, (sum, i) => sum + i, sum => sum * sum);

const totalSpent = aggregate(personsQuery, 0, (sum, p) => sum + p.spent);

const avgAge = aggregate(personsQuery,
    { ageSum: 0, count: 0 },
    ({ ageSum, count }, p) => ({ ageSum: p.age + ageSum, count: count + 1 }),
    ({ ageSum, count }) => ageSum / count
);

Embedded example:

const sum = integers.aggregate((sum, i) => sum + i);

const sumSquare = integers.aggregate((sum, i) => sum + i, sum => sum * sum);

const totalSpent = personsQuery.aggregate(0, (sum, p) => sum + p.spent);

const avgAge = personsQuery.aggregate(
    { ageSum: 0, count: 0 },
    ({ ageSum, count }, p) => ({ ageSum: p.age + ageSum, count: count + 1 }),
    ({ ageSum, count }) => ageSum / count
);

toArray

Creates an Array from iterator values.

Signature:

toArray<T>(source: Iterator<T>) => T[]

Basic example:

const personsArray = toArray(personsQuery);

Embedded example:

const personsArray = personsQuery.toArray();

toSet

Creates a Set from iterator values.

Signature:

toSet<T>(source: Iterator<T>) => Set<T>

Basic example:

const names = toSet(select(personQuery, p => p.name));

Embedded example:

const names = personsQuery.select(p => p.name).toSet();

toMap

Creates a Map according to a specified key selector function and an value selector function.

Signatures:

toMap<TKey, TValue>(source: Iterator<[TKey, TValue]>) => Map<TKey, TValue>

toMap<T, TKey>(
    source: Iterator<T>,
    keySelector: (item: T) => TKey
) => Map<TKey, T>

toMap<T, TKey, TValue>(
    source: Iterator<T>,
    keySelector: (item: T) => TKey,
    valueSelector: (item: T) => TValue
) => Map<TKey, TValue>

Basic example:

const persons = toMap(personQuery, p => p.id);
const names = toMap(personQuery, p => p.id, p => p.name);

Embedded example:

const persons = personQuery.toMap(p => p.id);
const names = personQuery.toMap(p => p.id, p => p.name);