0

I don't know how to formulate right. But I need to make next thing.

We have next data stucture:

a = [
    {
    name: "size",
    'values': ['S', 'M', 'L']
    },
    {
    name: 'color',
    'values': ['B', 'G', 'Y'],
    },
    {
    name: 'material',
    'values': ['X', 'Y']
    }
]

And from this need generate next array:

['SBX', 'SBY', 'SGX', 'SGY', 'SYX', 'SYY', 'MBX, 'MBY', ..., 'LYY']

Exists some algorithm for my task? Or simple example. Thank you!

3 Answers3

0

I'd do it this way :

let a = [
    {
       name: "size",
       'values': ['S', 'M', 'L']
    },
    {
       name: 'color',
       'values': ['B', 'G', 'Y'],
    },
    {
       name: 'material',
       'values': ['X', 'Y']
    }
]

let output = []

a[0].values.forEach( size => {
 a[1].values.forEach( color => {
  a[2].values.forEach( material =>{
   output.push(size+color+material)
  })
 })
})

console.log(output) // ['SBX', 'SBY', 'SGX', 'SGY', 'SYX', 'SYY', 'MBX, 'MBY', ..., 'LYY']
Jeremy Thille
  • 26,047
  • 12
  • 43
  • 63
0

First: combine your values in one array. you can do that using Array#reduce

var a = [
    {
    name: "size",
    'values': ['S', 'M', 'L']
    },
    {
    name: 'color',
    'values': ['B', 'G', 'Y'],
    },
    {
    name: 'material',
    'values': ['X', 'Y']
    }
]
// Merge values together in one array
var values = a.reduce((acc, item) => {
    acc.push(item.values);
    return acc;
}, []);

Then use a helper function to generate the possible values.

copied from this SO answer:

// Helper function
function allPossibleCases(arr) {
    if (arr.length == 1) {
    return arr[0];
    } else {
    var result = [];
    var allCasesOfRest = allPossibleCases(arr.slice(1));  // recur with the rest of array
    for (var i = 0; i < allCasesOfRest.length; i++) {
        for (var j = 0; j < arr[0].length; j++) {
        result.push(arr[0][j] + allCasesOfRest[i]);
        }
    }
    return result;
    }  
}

Then pass your big array to this function

var outPut = allPossibleCases(values);

All code:

var a = [{
        name: "size",
        'values': ['S', 'M', 'L']
    },
    {
        name: 'color',
        'values': ['B', 'G', 'Y'],
    },
    {
        name: 'material',
        'values': ['X', 'Y']
    }
]
// Merge values together in one array
var values = a.reduce((acc, item) => {
    acc.push(item.values);
    return acc;
}, []);

// Helper function
function allPossibleCases(arr) {
    if (arr.length == 1) {
        return arr[0];
    } else {
        var result = [];
        var allCasesOfRest = allPossibleCases(arr.slice(1)); // recur with the rest of array
        for (var i = 0; i < allCasesOfRest.length; i++) {
            for (var j = 0; j < arr[0].length; j++) {
                result.push(arr[0][j] + allCasesOfRest[i]);
            }
        }
        return result;
    }
}

var outPut = allPossibleCases(values);


console.log(outPut);
/*
 [
  "SBX",
  "MBX",
  "LBX",
  "SGX",
  "MGX",
  "LGX",
  "SYX",
  "MYX",
  "LYX",
  "SBY",
  "MBY",
  "LBY",
  "SGY",
  "MGY",
  "LGY",
  "SYY",
  "MYY",
  "LYY"
]
*/
Mohamed Abbas
  • 2,228
  • 1
  • 11
  • 19
0

Here is an working example, just process each array, concatenate all the items with existing array's all items and construct a new array, and go on...

var a = [{
        name: "size",
        'values': ['S', 'M', 'L']
    },
    {
        name: 'color',
        'values': ['B', 'G', 'Y'],
    },
    {
        name: 'material',
        'values': ['X', 'Y']
    }
]

function transformData(arr) {
    var res = [];
    var appendWithExisting = function(exist, curr) {
        var ret = [];
        if (!exist || !exist.length) {
            return curr.slice()
        }
        for (var i = 0; i < curr.length; i++) {
            var b = curr[i];
            for (var j = 0; j < exist.length; j++) {
                ret.push(exist[j] + b);
            }
        }
        return ret;
    }
    for (var idx = 0; idx < arr.length; idx++) {
        res = appendWithExisting(res, arr[idx].values);
    }
    return res;
}

console.log(transformData(a))
Koushik Chatterjee
  • 4,106
  • 3
  • 18
  • 32