Q:

JavaScript - Finding all combinations including individual and dual combinations?

I have an array of objects I am trying to find all the combinations for. I have got some code that finds all the combinations, however it only find the number of combinations based on the length of the input array.
For example if I use the below array and with the function below I get 27 potential combinations, however that doesn't include elements on their own or in twos.
[
[{ optionName: "red" },{ optionName: "blue"  },{ optionName: "green" }],
[{ optionName: "S" },{ optionName: "L" },{ optionName: "XL" }],
[{ optionName: "spotted" },{ optionName: "striped" },{ optionName: "lined" }],
]

For example I get combinations that look like this:
[{ optionName: "red" },{ optionName: "L"  },{ optionName: "spotted" }]
[{ optionName: "red" },{ optionName: "S"  },{ optionName: "spotted" }]
[{ optionName: "red" },{ optionName: "S"  },{ optionName: "lined" }]

However I want to also include combinations like:
[{ optionName: "red" }]
[{ optionName: "red" },{ optionName: "S"  }]
[{ optionName: "red" },{ optionName: "L"  }]

This is the code I am working with:
       var r = [],
        arg = arrayCombOptions,
        max = arg.length - 1;
      function helper(arr, i) {
        for (var j = 0, l = arg[i].length; j < l; j++) {
          var a = arr.slice(0);
          a.push(arg[i][j]);
          if (i == max) r.push(a);
          else helper(a, i + 1);
        }
      }
      helper([], 0);

How do I find all the combinations including individual and dual combinations? 

A:

You could add for each inner array a dummy like undefined, generate a cartesian product, map only arrays without undefined and slice the array from one, because the first is empty as well.

var data = [[{ optionName: "red" }, { optionName: "blue" }, { optionName: "green" }], [{ optionName: "S" }, { optionName: "L" }, { optionName: "XL" }], [{ optionName: "spotted" }, { optionName: "striped" }, { optionName: "lined" }]], 
    result = data
        .map(a => [undefined, ...a])
        .reduce((a, b) => a.reduce((r, v) => r.concat(b.map(w => [].concat(v, w))), []))
        .map(a => a.filter(Boolean))
        .slice(1);

console.log(result.length);
document.getElementById('out').innerHTML = JSON.stringify(result, null, 4);
<pre id="out"><pre>

