Get all possible options for a matrix in javascript Get all possible options for a matrix in javascript arrays arrays

Get all possible options for a matrix in javascript


This can be a good interview question.
See JS Bin for running example.

getAllPermutations(newItem);function getAllPermutations(item) {    var permutations = [];    getAllPermutations0(item, permutations, []);    console.log(permutations);}function getAllPermutations0(item, permutations, array) {    if (array && array.length === item.Settings.length) {        permutations.push(array.slice()); // The slice clone the array        return;    }    var index =  array.length;    var setting = item.Settings[index];    for (var i = 0; i < setting.values.length; i++) {        if (index === 0)            array =  [];        var currValue = setting.values[i];        array.push({            SettingName: setting.name,            value: currValue        });        getAllPermutations0(item, permutations, array);        array.pop(); // pop the old one first    }}


Here is a none recursive solution. It takes an empty or existing settings "matrix" and a values array, and return a new matrix as a combination of existing matrix content cloned for each new value, appended with pairs of new value setting items.

[A] -> [1,2] gives [A][1][A][2]

[A][1][A][2] -> [X,Y] gives [A][1][X][A][2][Y][A][2][X][A][1][Y]

and so on

function processSettings(settings, name, values) {  if (settings.length == 0) {    values.forEach(function(value) {      settings.push( [{ SettingName: name, value: value }] )    })  } else {    var oldSettings = JSON.parse(JSON.stringify(settings)), settings = [], temp, i = 0    for (i; i<values.length; i++) {      temp = JSON.parse(JSON.stringify(oldSettings))      temp.forEach(function(setting) {        setting.push( { SettingName: name, value: values[i] } )        settings.push(setting)      })     }   }   return settings}

You can now create the desired settings literal this way :

var settings = []for (var i=0; i<newItem.Settings.length; i++) {  var item = newItem.Settings[i]  settings = processSettings(settings, item.name, item.values)}

demo -> http://jsfiddle.net/b4ck98mf/

The above produces this :

[[{"SettingName":"color","value":"green"},{"SettingName":"size","value":"15"},{"SettingName":"gender","value":"male"}],[{"SettingName":"color","value":"blue"},{"SettingName":"size","value":"15"},{"SettingName":"gender","value":"male"}],[{"SettingName":"color","value":"red"},{"SettingName":"size","value":"15"},{"SettingName":"gender","value":"male"}],[{"SettingName":"color","value":"green"},{"SettingName":"size","value":"18"},{"SettingName":"gender","value":"male"}],[{"SettingName":"color","value":"blue"},{"SettingName":"size","value":"18"},{"SettingName":"gender","value":"male"}],[{"SettingName":"color","value":"red"},{"SettingName":"size","value":"18"},{"SettingName":"gender","value":"male"}],[{"SettingName":"color","value":"green"},{"SettingName":"size","value":"22"},{"SettingName":"gender","value":"male"}],[{"SettingName":"color","value":"blue"},{"SettingName":"size","value":"22"},{"SettingName":"gender","value":"male"}],[{"SettingName":"color","value":"red"},{"SettingName":"size","value":"22"},{"SettingName":"gender","value":"male"}],[{"SettingName":"color","value":"green"},{"SettingName":"size","value":"15"},{"SettingName":"gender","value":"female"}],[{"SettingName":"color","value":"blue"},{"SettingName":"size","value":"15"},{"SettingName":"gender","value":"female"}],[{"SettingName":"color","value":"red"},{"SettingName":"size","value":"15"},{"SettingName":"gender","value":"female"}],[{"SettingName":"color","value":"green"},{"SettingName":"size","value":"18"},{"SettingName":"gender","value":"female"}],[{"SettingName":"color","value":"blue"},{"SettingName":"size","value":"18"},{"SettingName":"gender","value":"female"}],[{"SettingName":"color","value":"red"},{"SettingName":"size","value":"18"},{"SettingName":"gender","value":"female"}],[{"SettingName":"color","value":"green"},{"SettingName":"size","value":"22"},{"SettingName":"gender","value":"female"}],[{"SettingName":"color","value":"blue"},{"SettingName":"size","value":"22"},{"SettingName":"gender","value":"female"}],[{"SettingName":"color","value":"red"},{"SettingName":"size","value":"22"},{"SettingName":"gender","value":"female"}]]


You can use Array.prototype.map(), for loop, while loop, Array.prototype.concat(). Iterate gender values; select each of color, size value in succession beginning at index 0 of either; iterating the furthest adjacent array from current gender, increment the index of the closest adjacent array; merge the resulting two gender arrays to form a single array containing all combinations of gender, color, size

var colors = newItem.Settings[0].values;var sizes = newItem.Settings[1].values;var gen = newItem.Settings[2].values;var i = sizes.length;var res = [].concat.apply([], gen.map(function(value, key) {  var next = -1;  var arr = [];  for (var curr = 0; curr < i; curr++) {    while (next < i - 1) {      arr.push([{        SettingName: "gender",        value: value      }, {        SettingName: "size",        value: sizes[curr]      }, {        SettingName: "color",        value: colors[++next]      }])    }    next = -1;  }  return arr}))

var newItem = {  "name": "new item",  "Settings": [{    "name": "color",    "values": [      "green",      "blue",      "red"    ]  }, {    "name": "size",    "values": [      "15",      "18",      "22"    ]  }, {    "name": "gender",    "values": [      "male",      "female"    ]  }]}var colors = newItem.Settings[0].values;var sizes = newItem.Settings[1].values;var gen = newItem.Settings[2].values;var i = sizes.length;var res = [].concat.apply([], gen.map(function(value, key) {  var next = -1;  var arr = [];  for (var curr = 0; curr < i; curr++) {    while (next < i - 1) {      arr.push([{        SettingName: "gender",        value: value      }, {        SettingName: "size",        value: sizes[curr]      }, {        SettingName: "color",        value: colors[++next]      }])    }    next = -1;  }  return arr}))document.querySelector("pre").textContent = JSON.stringify(res, null, 2)
<pre></pre>

plnkr http://plnkr.co/edit/C2fOJpfwOrlBwHLQ2izh?p=preview