Git Product home page Git Product logo

js-toolkit's Introduction

js-toolkit

My own collection of useful javascript things.

Warning

There are tests, but they are probably incomplete. Terminology may change. The interface may change. For demonstration purposes only.

array.shuffle

Shuffles an array into random order, in place. Returns the same array.

import { shuffle } from "js-toolkit/array";

const arr = [1, 2, 3, 4, 5];
shuffle(arr); // now in random order

If you want to monkey-patch the function so it is available on every array, do:

import { patch_array_shuffle } from "js-toolkit/array";
patch_array_shuffle();

let shuffled = [1, 2, 3, 4, 5].shuffle();

SaneSet

An extention of Set that has set methods on it. Includes is_empty(), difference()

import { SaneSet } from "js-toolkit/SaneSet";

function | what it does is_empty() | self-explanatory equals(other) | Shallowly check if the same elements are in both sets difference(other) | Compute the set difference between this and other intersection(...others) | Compute the intersection of this and the others union(...others) | The union of this and the others is_disjoint(...others) | Is this disjoint from all the others pop() | Remove and return a randomly selected element from the set. Throws Empty if the set is empty.

These functions are also available as stand-alone versions.

iter

Use the iter() function to get a custom iterable from a native iterable, or object. The iterator created from an object iterates over that object's own enumeratable keys and values.

The custom iterable is itself an iterable, and can be used in places which accepts an iterable, such as a for loop, or as the argument to a collection constructor that accepts building a new collection from an iterable. For example:

import { iter } from "js-toolkit";

for (const x of iter([1, 2, 3, 4, 5])) {
    console.log(x); // 1 2 3 4 5
}

for (const [key, value] of iter({a: 1, b: 2, c: 3})) {
    console.log(key, value); // a 1, b 2, c 3
}

const it = iter([1, 2, 3, 4, 5]).map(x => x ** 2);
let set1 = new Set(it); // set of 1 4 9 16 25

The iterable has a number of chainable methods on it. Usual suspects like .map() and .filter(), but also numerous others, that will alter what the iterable iterates over. (Yes, this is heavily inspired from Python's itertools). A few examples:

import { iter, count } from "js-toolkit";
count()                                // 0 1 2 3 4 5 6 7 8 9 10 11 12 ...
    .takewhile(x => x < 8)             // 0 1 2 3 4 5 6 7
    .filter(x => x % 2 === 0)          // 0 2 4 6
    .map(x => x * 3)                   // 0 6 12 18
    .sum();                            // 36

iter({ A: 1, B: 2, C: 3 })             // [A, 1] [B, 2] [C, 3]
    .map(([k, v]) => [k + k, v * v])   // [AA, 1 * 1] [BB, 2 * 2] [CC, 3 * 3]
    .collect_object();                 // { AA: 1, BB: 4, CC: 9 }

Producers (starting points of iteration):

count, range, fibonacci, enumerate, repeat, chain, primes, intersperse, zip.

Processors (alters what the iterator iterator, and processes it in some way)

filter, map, take, takewhile, takeuntil, skip, group

Finishers (consumes an iterator to produce a single result

any, all, count, join, first, last, reduce, average, sum, max, min

Collectors

group()

Use .group() to create sub-iterators of different "groups" of values coming in from the iterator chain. The function passed to .group() determines how to define which group a value belongs to. .match(value) will create a sub-iterator, that will only recieve items which belong to that group.

After the last match arm (along with it's iterator chain) has been specified, use .gather() to return to the outer iterator. The elements .gather() will iterate over, are 2-tuples. The first element being the match_arm value, the second being the result of the iterator chain for that match arm.

The example below hopefully helps clear things up.

const items = [
    { type: "A", value: 1 },
    { type: "B", value: 10 },
    { type: "C", value: 100 },
    { type: "A", value: 2 },
    { type: "B", value: 20 },
    { type: "C", value: 200 },
];

const generated =
    iter(items)
    .group(({ type }) => type)
      .match("A").map(({ value }) => value).sum()
      .match("B").map(({ value }) => value).sum()
      .match("C").map(({ value }) => value).sum()
    .gather()
    .collect_object();

// generated === { A: 3, B: 30, C: 300 };

js-toolkit's People

Contributors

phaqui avatar

Stargazers

Thomas Buckley-Houston avatar

Watchers

 avatar

js-toolkit's Issues

add "dig", or a way to recurse into subarrays, or sub items that can be iterated over?

dig(), a function (processor or producer, or both?) that should recurse into inner arrays, and yield out every sub item that is not iterable, like numbers. Maybe dig() can even be customizable, stopping recursion on certain types or certain objects, or at some maximum depth.

so we can have this, clearly:

iter([1, 2, 3]).collect_array() === [1, 2, 3]
iter([ [1, 2], 3]).collect_array() === [ [1, 2], 3]

but, then suppose we want to recurse into all the numbers, and do something with them...

iter([1, 2, 3]).map(n => n * 2).collect_array() === [2, 4, 6]
iter([ [1, 2], 3]).map(n => n * 2).collect_array() === [ NaN, 6 ]

because obviously [ 1, 2 ] * 2 is NaN.

Maybe there are ways to solve this in an easy way that I can't think of right at this time, but what if...

// WHAT IF...
iter([ [1, 2], 3]).dig().map(n => n * 2).collect_array() === [2, 4, 6]

motivation

count total number of inner, non-iterable items? Sure you could recursively flatten the array first, but..

// WHAT IF...
iter([ 1, [2, 3], [4, [5, 6, 7]]]).dig().count() === 7

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.