Skip to content

rbuckton/iterable-query

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

51 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

iterable-query - Query API for JavaScript Iterables and Async Iterables

// TypeScript
import { Query } from "iterable-query";

// JavaScript (CommonJS)
const { Query } = require("iterable-query");

let q = Query
  .from(books)
  .filter(book => book.author === "Alice")
  .groupBy(book => book.releaseYear);

// TypeScript (functional style)
import { filter, groupBy } from "iterable-query/fn";

// JavaScript (functional style, CommonJS)
const { filter, groupBy } = require("iterable-query/fn")

let i = groupBy(
  filter(books,
    book => book.author === "Alice"),
    book => book.releaseYear);

iterable-query is a library that provides a query API for ES6 iterables, adding numerous operations found in other languages like Haskell, Scala, and C# (.NET).

Installing

For the latest version:

npm install iterable-query

Documentation

Examples

Filtering

let gen = function*() {
  yield 1;
  yield 2;
  yield 3;
};

let evens = Query
  .from(gen())
  .filter(i => i % 2 === 0);

let odds = Query
  .from(gen())
  .where(i => i % 2 === 1); // alias for `filter`

Sorting

let books = [
  { id: 1, title: "QueryJS a query API for JavaScript", author: "Smith, David" },
  { id: 2, title: "Iterators and You", author: "Smith, Bob" },
  { id: 3, title: "All the Queries", author: "Smith, Frank" }
]

let ordered = Query
  .from(books)
  .orderBy(book => book.title)
  .thenBy(book => book.author);

let result = [...ordered];

Grouping

let groups = [
  { id: 1, name: "Admin" },
  { id: 2, name: "Standard User" }
];
let users = [
  { id: 1, name: "Bob", groupId: 2 },
  { id: 2, name: "Alice", groupId: 1 },
  { id: 3, name: "Tom", groupId: 2 }
];

let usersByGroup = Query
  .from(groups)
  .groupJoin(users, group => group.id, user => user.id);

for (let groupUsers of usersByGroup) {
  print(groupUsers.key);
  print('======');
  for (let user of groupUsers) {
    print(user.name);
  }
}

Hierarchies

let doc = Query
  .hierarchy<Node>(document.body, {
    parent(node: Node) { return node.parentNode; },
    children(node: Node) { return node.childNodes; }
  });

// disable all buttons
doc
  .descendants()
  .where((node: Node): node is HTMLButtonElement => node.type === "BUTTON")
  .forEach(node => {
    node.disabled = true;
  });

// get all thumbnails
let thumbnails = doc
  .descendants()
  .filter(node => node.type === "IMG")
  .map(node => <HTMLImageElement>node)
  .filter(img => img.height < 32 && img.width < 32)
  .toArray();

Supported ECMAScript Editions

ES2017 Support (default)

The iterable-query library can be used in an ES2017-compatible runtime by importing "iterable-query":

// TypeScript
import { Query } from "iterable-query";

// JavaScript
const { Query } = require("iterable-query");

// TypeScript (functional style)
import { filter, groupBy } from "iterable-query/fn";

// JavaScript (functional style)
const { filter, groupBy } = require("iterable-query/fn");

The default implementation requires a host that supports ES2017 at a minimum. This means support for:

  • Symbol and Symbol.iterator
  • Promise
  • Map
  • Set
  • WeakMap
  • WeakSet
  • for..of
  • Generator Functions
  • Async Functions

The following ES2018 features are polyfilled:

  • Symbol.asyncIterator (via Symbol.for("Symbol.asyncIterator")).

The following ES2018 features are not required to use the default (ES2017) version:

  • Async Generator Functions (internal use is transpiled)

In addition, we also provide downlevel support for ES2015 and ES5.

ES2015 Support

The iterable-query library can be used in an ES2015-compatible runtime by importing "iterable-query/es2015":

// TypeScript
import { Query } from "iterable-query/es2015";

// JavaScript
const { Query } = require("iterable-query/es2015");

// TypeScript (functional style)
import { filter, groupBy } from "iterable-query/es2015/fn";

// JavaScript (functional style)
const { filter, groupBy } = require("iterable-query/es2015/fn");

The ES2015 implementation requires a host that supports ES2015 at a minimum. This means support for:

  • Symbol and Symbol.iterator
  • Promise
  • Map
  • Set
  • WeakMap
  • WeakSet
  • for..of
  • Generator Functions

The following ES2018 features are polyfilled:

  • Symbol.asyncIterator (via Symbol.for("Symbol.asyncIterator")).

The following ES2017 features are not required to use the ES2015 version:

  • Async Functions (internal use is transpiled)

The ES2015 version of the library has all of the same features as the normal version.

ES5 Support

The iterable-query library can be used in an ES5-compatible runtime by importing "iterable-query/es5":

// TypeScript
import { Query } from "iterable-query/es5";

// JavaScript
var iq = require("iterable-query/es5"),
    Query = iq.Query;

// TypeScript (functional style)
import { filter, groupBy } from "iterable-query/es2015/fn";

// JavaScript (functional style)
var fn = require("iterable-query/es2015/fn"),
    filter = fn.filter,
    groupBy = fn.groupBy;

The ES5 version of the library has all of the same features as the normal version.

The ES5 implementation requires a host that supports ES5 at a minimum. This means support for:

  • Object.create and Object.defineProperty

The following ES2015 features are not polyfilled and require you to supply a runtime polyfill:

  • Promise

The following ES2015 features are polyfilled:

  • Symbol and Symbol.iterator (which produce strings)
  • Map
  • Set
  • WeakMap
  • WeakSet

The following ES2017 features are polyfilled:

  • Symbol.asyncIterator (via Symbol.for("Symbol.asyncIterator")).

The following ES2015 and ES2017 features are not required to use the ES5 version:

  • for..of
  • Generator Functions (internal use is transpiled)
  • Async Functions (internal use is transpiled)