ehmicky / fast-cartesian

Fast cartesian product

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

result of [], ['e'] should be ['e']

xenoterracide opened this issue · comments

Guidelines

  • Please search other issues to make sure this bug has not already been reported.
  • If this is related to a typo or the documentation being unclear, please click on the relevant page's Edit button (pencil icon) and suggest a correction instead.

Describe the bug

shouldn't product be ['e'] I get [] instead

const product = fastCartesian([[],['e']) // ['e']

Steps to reproduce

import { expect } from 'chai'
import fastCartesian from 'fast-cartesian'
import { describe, it } from 'mocha'

describe('fastCartesian', () => {
  it('basic', () => {
    const product = fastCartesian([[], ['e']]) // ['e']
    expect(product).to.be.deep.eq(['e'])
  })
})

Configuration

n/a, if test modules don't work you should be able to swap them for anything else

Environment

❯ npx envinfo --system --binaries --browsers --npmPackages fast-cartesian && npm explain fast-cartesian

  System:
    OS: macOS 11.6.5
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Memory: 623.13 MB / 16.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 16.14.2 - ~/.asdf/installs/nodejs/16.14.2/bin/node
    npm: 8.6.0 - ~/.asdf/plugins/nodejs/shims/npm
  Browsers:
    Chrome: 100.0.4896.127
    Safari: 15.4

fast-cartesian@5.1.0

I'm using 5.1.0 because we have a problem with esm modules that I haven't had time to fix

Pull request (optional)

  • I can submit a pull request.

in fact, it happens if any of the inputs are empty arrayed s

Hi @xenoterracide,

Thanks a lot for your input.

This is expected behavior: if any of the arrays is empty, the returned array should be empty too.

From a mathematical standpoint, cartesian products with at least one empty set result in an empty set.

From a more pragmatic standpoint, there are several reasons why the mathematical definition makes sense. For example, there is a guarantee that each element of the result array corresponds to an element in one of the argument arrays. Let's say you are doing const d = fastCartesian([a, b, c]). Then, d[*][0] is guaranteed to be an element of a, d[*][1] an element of b and d[*][2] an element of c. If one of the arguments is an empty array, the only way to keep this guarantee is to return an empty array.

Another guarantee is the size of the return array being a product of the sizes of the argument arrays. Re-using above example, d.length === a.length * b.length * c.length.

There are more examples and more practical reasons explaining this behavior, beyond the mathematical one.

That being said, I understand this might be an issue with your particular usage of this library, i.e. I can see situations where empty arrays as result would be a problem. If that's the case, you can work around this problem by filtering out any empty arrays used as input:

fastCartesian(arrays.filter(array => array.length !== 0))

Thanks for your feedback though!