fix massive issue in getAllPossibleCombinations

This commit is contained in:
Henry Jameson 2024-03-25 18:18:48 +02:00
parent 1050fed558
commit c1568ad2ba
2 changed files with 29 additions and 5 deletions

View File

@ -11,18 +11,28 @@ export const unroll = (item) => {
}
// This gives you an array of arrays of all possible unique (i.e. order-insensitive) combinations
// Can only accept primitives. Duplicates are not supported and can cause unexpected behavior
export const getAllPossibleCombinations = (array) => {
const combos = [array.map(x => [x])]
for (let comboSize = 2; comboSize <= array.length; comboSize++) {
const previous = combos[combos.length - 1]
const selfSet = new Set()
const newCombos = previous.map(self => {
const selfSet = new Set()
self.forEach(x => selfSet.add(x))
const nonSelf = array.filter(x => !selfSet.has(x))
return nonSelf.map(x => [...self, x])
})
const flatCombos = newCombos.reduce((acc, x) => [...acc, ...x], [])
combos.push(flatCombos)
const uniqueComboStrings = new Set()
const uniqueCombos = flatCombos.map(x => x.toSorted()).filter(x => {
if (uniqueComboStrings.has(x.join())) {
return false
} else {
uniqueComboStrings.add(x.join())
return true
}
})
combos.push(uniqueCombos)
}
return combos.reduce((acc, x) => [...acc, ...x], [])
}
@ -31,7 +41,7 @@ export const getAllPossibleCombinations = (array) => {
export const genericRuleToSelector = components => (rule, ignoreOutOfTreeSelector, isParent) => {
if (!rule && !isParent) return null
const component = components[rule.component]
const { states, variants, selector, outOfTreeSelector } = component
const { states = {}, variants = {}, selector, outOfTreeSelector } = component
const applicableStates = ((rule.state || []).filter(x => x !== 'normal')).map(state => states[state])

View File

@ -11,9 +11,23 @@ import {
describe.only('Theme Data 3', () => {
describe('getAllPossibleCombinations', () => {
it('test simple case', () => {
it('test simple 3 values case', () => {
const out = getAllPossibleCombinations([1, 2, 3]).map(x => x.sort((a, b) => a - b))
expect(out).to.eql([[1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]])
expect(out).to.eql([
[1], [2], [3],
[1, 2], [1, 3], [2, 3],
[1, 2, 3]
])
})
it('test simple 4 values case', () => {
const out = getAllPossibleCombinations([1, 2, 3, 4]).map(x => x.sort((a, b) => a - b))
expect(out).to.eql([
[1], [2], [3], [4],
[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4],
[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4],
[1, 2, 3, 4]
])
})
})