theprogrammablemind
Version:
155 lines (138 loc) • 3.93 kB
JavaScript
const { isArray, isObject, isCompound } = require('./helpers')
const _ = require('lodash')
const DEBUG = (...args) => {
// DEBUG(...args)
}
const flattens = (markers, contexts) => {
let flats = []
for (const context of contexts) {
// const [more, _] = flatten(markers, context)
const more = flatten(markers, context)[0]
flats = flats.concat(more)
}
return flats
}
const accumulate = (accumulator, nexts) => {
const accumulatorPrime = []
for (const current of accumulator) {
for (const next of nexts) {
const nextCurrent = _.clone(current)
nextCurrent.push(next)
accumulatorPrime.push(nextCurrent)
}
}
return accumulatorPrime
}
const cartesianHelper = (accumulator, b, ...c) => {
if (b) {
return cartesianHelper(accumulate(accumulator, b), ...c)
} else {
return accumulator
}
}
const cartesian = (...factors) => {
return cartesianHelper([[]], ...factors)
}
const zip = (a1, a2) => {
return a1.map(function (value, index) {
return [value, a2[index]]
})
}
const flattenListHelper = (markers, values) => {
const flats = []
let wasFlattened = false
let singles = []
for (const value of values) {
if (!isCompound(value)) {
singles.push(value)
} else {
const [more, wf] = flatten(markers, value)
if (wf) {
wasFlattened = wasFlattened || wf
flats.push(more)
} else {
singles = singles.concat(more)
}
}
}
// product does weirdness with only choice
if (!wasFlattened) {
return [[singles], wasFlattened]
} else {
const results = []
for (const flat of cartesian(...flats)) {
results.push(singles.concat(flat))
}
return [results, wasFlattened]
}
}
// returns (list, wasFlattened)
const flatten = (markers, value) => {
if (isArray(value)) {
return flattenListHelper(markers, value)
}
if (value.flatten === false) {
return [[value], false]
}
const marker = value.marker
let properties = value
// if you want to pull up conj properties fix this to do to the other part
// split = marker in markers
const split = markers.includes(marker)
if (split) {
if ('value' in properties) {
flattenedValues = []
for (const v of properties.value) {
if (v.flatten) {
flattenedValues = flattenedValues.concat(flatten(markers, v)[0])
} else {
flattenedValues.push(v)
}
}
return [flattenedValues, true]
} else {
return [[value], false]
}
}
const keys = []
const valuess = []
const unchanged = {}
DEBUG('properties', JSON.stringify(properties, null, 2))
for (const key in properties) {
let wf = false
let values
// if isinstance(properties[key], Context) {
if (isObject(properties[key])) {
const context = properties[key];
[values, wf] = flatten(markers, context)
// } else if (isinstance(properties[key], list)) {
} else if (isArray(properties[key])) {
[values, wf] = flattenListHelper(markers, properties[key])
} else {
values = [properties[key]]
}
if (wf) {
keys.push(key)
valuess.push(values)
} else {
unchanged[key] = values[0]
}
}
const propertiess = []
DEBUG('-----------> valuess', JSON.stringify(valuess))
DEBUG('-----------> cartesian(valuess)', JSON.stringify(cartesian(valuess)))
// for (let values of itertools.product(*valuess)) {
const cp = cartesian(...valuess)
DEBUG('-----------> cp', JSON.stringify(cp))
for (const values of cartesian(...valuess)) {
// properties = copy.deepcopy(unchanged)
properties = _.cloneDeep(unchanged)
// for key, value in zip(keys, values) {
for (const [key, value] of zip(keys, values)) {
properties[key] = value
}
propertiess.push(properties)
}
return [propertiess, valuess.length > 0]
}
module.exports = { flattens, flatten, cartesian, accumulate }