I have written the following Javascript function. It is supposed to return all the unique permutations (including partial permutations) of the elements of the input array; it is coded as a generator (introduced by function*
and returning values using yield
), so that the values are evaluated lazily on demand.
function* permute(arr) {
if (arr.length == 1)
yield arr
else if (arr.length) {
for (let i of arr) {
const value = arr[i]
if (arr.indexOf(value) == i) {
yield [value]
const others = arr.slice(0, i).concat(arr.slice(i+1))
for (let perm of permute(others))
yield [value, ...perm]
}
}
}
}
To test it, I used the following Jest unit test:
describe("Permute tests", () => {
test("No duplicates", () => {
const input = "abc".split("")
const expected = "a ab abc ac acb b ba bac bc bca c ca cab cb cba"
.split(" ")
for (let x of permute(input))
expect(x.join("")).toBe(expected.shift())
expect(expected.length).toBe(0)
})
})
But when I run this, it doesn't give the expected results. The test fails at the last line because expected.length
is not zero, it is 15 as no results from the generator have been processed. And this is borne out by the fact that if I put a breakpoint on the first statement in the generator function, it is not hit; it seems that next() is never called on the generator.
I have written other generators, and successfully tested them, but this one consistently doesn't work. What am I doing wrong?
Environment: NodeJS 14.16.0 and npm 7.10.0 on Windows 10 (or Ubuntu 20.04); Jest 26.6.3.