dankogai / js-combinatorics

power set, combination, permutation and more in JavaScript
MIT License
742 stars 97 forks source link

Use native generators instead of custom iteration methods #65

Closed hbarcelos closed 4 years ago

hbarcelos commented 4 years ago

Hi, first of all, thanks a lot for building this awesome lib. I was almost going to implement my own, but I found this and it suits my needs almost perfectly.

The implementation of most functions in this lib is lazy and that's really a good design choice because combinatorics are things just bound to explode in size. However, being forced to consume them in while loops feels a bit outdated.

const cmb = combination([1, 2, 3], 2);
let item;
while((item = cmb.next()) {
  console.log(item);
}

You are probably aware, but JavaScript Generators gives us a more native way of expressing lazy behavior.

I wrote some tiny wrappers around the functions this lib exposes, such as:

import { combination as originalCombination } from 'js-combinatorics';

export default function combination(arr, size) {
  return {
    *[Symbol.iterator]() {
      const cmb = originalCombination(arr, size);

      let item;
      while ((item = cmb.next())) {
        yield item;
      }
    },
  };
}

This way, I can consume it with a for..of loop:

const cmb = combination([1, 2, 3], 2);
for (let item of cmb) {
  console.log(i);
}

Or could even use the spread operator to turn it into an array:

const cmb = combination([1, 2, 3], 2);
const arr = [...cmb];
console.log(arr);

Maybe this could be made built-in. If you are willing to give this a try, I could work on a PR as soon as I have some time off.

dankogai commented 4 years ago

Of course I am willing to give it a try! According to:

generators are supported virtually all browsers but IE, which we can ignore now.

dankogai commented 4 years ago

https://github.com/dankogai/js-combinatorics/commit/a299e792177357da7707f85c765b5b685d4df712