如何创建此对象的所有组合';JavaScript中的s键/值?

如何创建此对象的所有组合';JavaScript中的s键/值?,javascript,algorithm,recursion,combinations,permutation,Javascript,Algorithm,Recursion,Combinations,Permutation,我有以下JavaScript对象结构: var options = { optionOne: [true, false], optionTwo: [true, false], optionThree: [ null, {property1: 9, property2: 7}, {property1: 4, property2: 12}, {property1: 16, property2: 14} ]

我有以下JavaScript对象结构:

var options = {
    optionOne: [true, false],
    optionTwo: [true, false],
    optionThree: [
        null,
        {property1: 9, property2: 7},
        {property1: 4, property2: 12},
        {property1: 16, property2: 14}
    ]
};
请注意,此对象中的键/对数将有所不同。因此实际上可能有
optionFour
optionFive
,等等,每个选项的数组可以有任意数量或类型的值

我需要遍历此对象并创建一个数组,其中包含所有可能选项组合的对象:

[
    {optionOne: true,  optionTwo, true,  optionThree: null},
    {optionOne: false, optionTwo, true,  optionThree: null},
    {optionOne: true,  optionTwo, false, optionThree: null},
    {optionOne: false, optionTwo, false, optionThree: null},
    {optionOne: true,  optionTwo, true,  optionThree: {property1: 9, property2: 7}},
    {optionOne: false, optionTwo, true,  optionThree: {property1: 9, property2: 7}},
    {optionOne: true,  optionTwo, false, optionThree: {property1: 9, property2: 7}},
    {optionOne: false, optionTwo, false, optionThree: {property1: 9, property2: 7}},
    {optionOne: true,  optionTwo, true,  optionThree: {property1: 4, property2: 12}},
    {optionOne: false, optionTwo, true,  optionThree: {property1: 4, property2: 12}},
    {optionOne: true,  optionTwo, false, optionThree: {property1: 4, property2: 12}},
    {optionOne: false, optionTwo, false, optionThree: {property1: 4, property2: 12}},
    {optionOne: true,  optionTwo, true,  optionThree: {property1: 16, property2: 14}},
    {optionOne: false, optionTwo, true,  optionThree: {property1: 16, property2: 14}},
    {optionOne: true,  optionTwo, false, optionThree: {property1: 16, property2: 14}},
    {optionOne: false, optionTwo, false, optionThree: {property1: 16, property2: 14}}
]
我正在为如何实现这一点而努力,但我相当有信心答案在于递归

上帝能帮我吗

function getCombinations(options, optionIndex, results, current) {
    var allKeys = Object.keys(options);
    var optionKey = allKeys[optionIndex];

    var vals = options[optionKey];

    for (var i = 0; i < vals.length; i++) {
        current[optionKey] = vals[i];

        if (optionIndex + 1 < allKeys.length) {
            getCombinations(options, optionIndex + 1, results, current);
        } else {
            // The easiest way to clone an object.
            var res = JSON.parse(JSON.stringify(current));
            results.push(res);
        }
    }

    return results;
}

这是一项工作。

这是一项基于Dmytro的改进:

函数getPermutations(对象,索引=0,当前={},结果=[]){ 常量键=对象。键(对象); 常量键=键[索引]; 常量值=对象[键]; for(值的常量值){ 当前[键]=值; 常数nextIndex=索引+1; if(nextIndex<键长度){ this.getPermutations(对象、nextIndex、当前、结果); }否则{ const result=Object.assign({},当前); 结果。推(结果); } } 返回结果; } 改进:

  • 适用于任何类型的值,即使该值是函数
  • 默认参数值,可以通过以下方式轻松调用:
    const p=getPermutations(object)
  • 语义上的细微改进

这是最近重新出现的,我认为现代JS提供了一种更简洁的编写方法

const叉积=(xss)=>
reduce((xs,ys)=>xs.flatMap(x=>ys.map(y=>[…x,y]),[[]))
常量组合=(o,键=对象。键(o),VAL=对象。值(o))=>
crossproduct(vals).map(xs=>Object.fromEntries(xs.map((x,i)=>[keys[i],x]))
const options={optionOne:[true,false],optionTwo:[true,false],optionTree:[null,{property1:9,property2:7},{property1:4,property2:12},{property1:16,property2:14}
log(JSON.stringify(
组合(选项)
,null,4))

。作为控制台包装器{max height:100%!important;top:0}
这个怎么样-哈--这正是我在过去一个小时里一直在寻找并试图建模的一个:)@ChadJohnson为了更好的可用性,我也会将它包装到一个类中。然后您可以这样使用它:
(新的Permuter(选项)).getPermutations()
。或者类似的,不需要传入基递归值。谢谢。我希望你和你在乌克兰的家人一切顺利!很好的解决方案!一个小建议是添加默认参数值,这样我们就可以只通过传递对象来调用该方法。谢谢。你是救命恩人
var results = getCombinations(options, 0, [], {});
function getPermutations(object, index = 0, current = {}, results = []) {
  const keys = Object.keys(object);
  const key = keys[index];
  const values = object[key];

  for (const value of values) {
    current[key] = value;
    const nextIndex = index + 1;

    if (nextIndex < keys.length) {
      this.getPermutations(object, nextIndex, current, results);
    } else {
      const result = Object.assign({}, current);
      results.push(result);
    }
  }
  return results;
}