1
var groupArrays = {
    "group1" : [
        "volvo",
        "bmw",
        "audi"
    ],
    "group2" : [
        "red"
    ],
    "group3" : [
        "1991"
    ]
};

This object is created after filtering a list of cars, I would like to create some css selectors with this to use in javascript to show filtered elements. So basically what I want is an array with possible selectors, something like this:

var selectors = [".volvo.red.1991", ".bmw.red.1991", ".audi.red.1991"];

What's the easiest method here to create the selectors array if the number of groups is unknown?

2
  • 1
    You'll need to show more data for us to understand what the grouping pattern is. What does one do if there is more than one item in group2 or group3? It isn't clear what the algorithm would be for building the selectors. Are you just trying to build all possible combinations of group1, group2 and group3? Commented Mar 6, 2014 at 21:36
  • Continuing that train of thought: What if the user hadn’t selected any brands? I don’t think your problem can be solved elegantly with a few nested loops. If we consider the filter design: Why do we need to select 1991 or red three times? Commented Mar 6, 2014 at 21:46

3 Answers 3

1
var groupArrays = {
    "group1": [
         "volvo",
         "bmw",
         "audi"
     ],
     "group2": [
         "red"
     ],
     "group3": [
         "1991"
     ]
};

var selectors = [];
var selector;

for (var g1 = 0; g1 < groupArrays.group1.length; g1++) {
    for (var g2 = 0; g2 < groupArrays.group2.length; g2++) {
        for (var g3 = 0; g3 < groupArrays.group3.length; g3++) {
            selector = "." + groupArrays.group1[g1] +
                        "." + groupArrays.group2[g2] +
                        "." + groupArrays.group3[g3];
            selectors.push(selector);
        }
    }
}

console.log(selectors);

JS Fiddle

Updated code for any number of groups

var groupArrays = {
    "group1": [
        "volvo",
        "bmw",
        "audi"
    ],
    "group2": [
        "red","green"
    ],
    "group3": [
        "1991","1992"
    ]
};

var selectors = [];
var values = [];
var ga = [];

for (var group in groupArrays) {
    ga.push(groupArrays[group]);
}

traverse(ga, 0);

console.log(selectors);

function traverse(ga, index) {
    if (index >= ga.length) {
        selectors.push("." + values.join("."));

        return;
    }

    var hold = ga[index].slice(0);
    var gacopy = ga[index];

    while(gacopy.length > 0) {
        var pickedValue = gacopy[gacopy.length - 1];
        values.push(pickedValue);
        gacopy.pop();

        traverse(ga, index + 1);

        values.splice(values.indexOf(pickedValue), 1);
    }

    ga[index] = hold;
}

JS Fiddle

Sign up to request clarification or add additional context in comments.

1 Comment

The number of groups is unknown
0

Just a simple series of nested loops will do this. You might have some problems with the class 1991 beginning with a number, though.

var selectors = [];
var i = groupArrays.group1.length,
    j,
    k;
while (i--) {
    j = groupArrays.group2.length;
    while (j--) {
        k = groupArrays.group3.length;
        while (k--) {
            selectors.push(
                '.' + groupArrays.group1[i] +
                '.' + groupArrays.group2[j] +
                '.' + groupArrays.group3[k]
            );
        }
    }
}
selectors; // [".audi.red.1991", ".bmw.red.1991", ".volvo.red.1991"]

If you have an unknown number of items in groupArrays, you may need to for..in loop over it and recurse with the resulting keys.

1 Comment

The number of groups is unknown
0

You can use the map function

var selectors = [];
groupArrays["group1"].map(function(x) {
    groupArrays["group2"].map(function(y) {
        groupArrays["group3"].map(function(z) {
                    selectors.push('.' + x + '.' + y + '.' + z)})})});

1 Comment

The number of groups is unknown

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.