Search code examples
javascriptgroupingnested-loops

Javascript Complex Grouping


I need help figuring out how I can loop through the Source Object to get the Output Strings. I currently have some nested for loops but I wind up missing one of the combinations or I get too much. The Number of Categories and Filters will vary

Source Object

var Source = {Cat1:{Filter1:'f1',Filter2:'f2'},
              Cat2:{Filter3:'f3',Filter4:'f4'},
              Cat3:{Filter5:'f5'}};

Output Strings

Filter1 Filter3 Filter5,
Filter1 Filter4 Filter5,
Filter2 Filter3 Filter5,
Filter2 Filter4 Filter5

Solution

  • Try this, this will return Array of arrays:

    function cartesianProduct(paramArray) {
    
      function addTo(curr, args) {
    
        var i, copy, 
            rest = args.slice(1),
            last = !rest.length,
            result = [];
    
        for (i = 0; i < args[0].length; i++) {
    
          copy = curr.slice();
          copy.push(args[0][i]);
    
          if (last) {
            result.push(copy);
    
          } else {
            result = result.concat(addTo(copy, rest));
          }
        }
    
        return result;
      }
    
    
      return addTo([], Array.prototype.slice.call(arguments));
    };
    
    var Source = {Cat1:{Filter1:'f1',Filter2:'f2'},
                  Cat2:{Filter3:'f3',Filter4:'f4'},
                  Cat3:{Filter5:'f5'}};
    
    // var cats = [];
    var filters = [];
    
    for(var c in Source) {
      filters.push([]);
      for(var f in Source[c])
        filters[filters.length - 1].push(f);
    }
    
    
    console.log(cartesianProduct.apply(this || window, filters));
    

    HTH