简体   繁体   中英

How to combine values from multiple arrays to create a new combined array

I'm working on a shopping site and want to give my users the ability to dynamically create multiple products based on variants they specify. I allow these users to create any number of 'Types', which define things like Size, Colour, or Capacity. But the user can specify the name of this and the number of types they want.

Within each Type, I also allow the user to configure multiple Choices. For example, the type Size might have choices Small, Medium, Large. Again the user can define the names of these fields and there shouldn't be any limit to how many fields they can create.

After the user has finished defining their product, I have an array for types and inside each type, an array for choices.

As a sample, a mobile phone product might have the following type and choice structure:

[
  {
  'id': 1,
  'type': 'Colour',
  'options': ['Black', 'White', 'Gold']
  },
  { 
  'id': 2,
  'type': 'Size',
  'options': ['Standard', 'Large"']
  },
  { 
  'id': 3,
  'type': 'Capacity',
  'options': ['32GB', '64GB', '128GB']
  }
]

From this data, I want to create 18 (3*2*3) possible product variants for which the user can specify specific price, weight, or SKU options. To end up with the following variants:

Black - Standard - 32GB
Black - Standard - 64GB
Black - Standard - 128GB
Black - Large - 32GB
Black - Large - 64GB
Black - Large - 128GB
White - Standard - 32GB
White - Standard - 64GB
White - Standard - 128GB
White - Large - 32GB
White - Large - 64GB
White - Large - 128GB
Gold - Standard - 32GB
Gold - Standard - 64GB
Gold - Standard - 128GB
Gold - Large - 32GB
Gold - Large - 64GB
Gold - Large - 128GB

Which I can imagine being in an array like this:

[
  {
    'variant_id': 1,
    'options':
      [{ 'type': 'Colour', 'choice': 'Black' },
      { 'type': 'Size', 'choice' 'Standard' },
      { 'type': 'Capacity', 'choice' '32G' }]
  },
  {
    'variant_id': 2,
    'options':
      [{ 'type': 'Colour', 'choice': 'Black' },
      { 'type': 'Size', 'choice' 'Standard' },
      { 'type': 'Capacity', 'choice' '64GB' }]
  },
  {
    'variant_id': 3,
    'options':
      [{ 'type': 'Colour', 'choice': 'Black' },
      { 'type': 'Size', 'choice' 'Standard' },
      { 'type': 'Capacity', 'choice' '128GB' }]
  }
<snip>

My question is how I can create a loop that will allow me to iterate over the various types and choices to create my final variant list? I'm having a hard time visualising just how I could go about delivering this function.

Try the below code. It does exactly what you want in pure javascript. The generateOutput function is called in a loop for the options of first element, and then generateOutput function is called recursively generating the required result. Its hard to explain the logic in writing. Just add debuggers and to understand the flow. Best of luck.

 var data = [{ 'id': 1, 'type': 'Colour', 'options': ['Black', 'White', 'Gold'] }, { 'id': 2, 'type': 'Size', 'options': ['Standard', 'Large"'] }, { 'id': 3, 'type': 'Capacity', 'options': ['32GB', '64GB', '128GB'] }]; function generateOutput(dataIndex, optionIndex) { var option, result, i, subResult; option = { type: data[dataIndex].type, choice: data[dataIndex].options[optionIndex] }; if (dataIndex == data.length - 1) { result = { isLast: true, options: [option] } return result; } result = []; for (i = 0; i < data[dataIndex + 1].options.length; i++) { subResult = generateOutput(dataIndex + 1, i); if (subResult.isLast) { subResult.options.unshift(option); result.push(subResult.options); } else { result = result.concat(subResult); } } if (!subResult.isLast) { for (var j = 0; j < result.length; j++) { result[j].unshift(option); } } return result; } function getOutput() { var result = [], option, i; for (i = 0; i < data[0].options.length; i++) { option = { type: data[0].type, choice: data[0].options[i] }; var subResult = generateOutput(0, i); if (subResult.isLast) { result.push(subResult.options); } else { result = result.concat(subResult); } } var output = []; for (i = 0; i < result.length; i++) { output.push({ variant_id: (i+1), options: result[i] }) } return output; } console.log(getOutput()); 

here is some jquery code using various jquery array methods

var list = [{
    'id': 1,
        'type': 'Colour',
        'options': ['Black', 'White', 'Gold']
}, {
    'id': 2,
        'type': 'Size',
        'options': ['Standard', 'Large']
}, {
    'id': 3,
        'type': 'Capacity',
        'options': ['32GB', '64GB', '128GB']
}];

var return_list = [];
var prev_options = list[0].options;

$.each(list, function (index, value) {
    if (index == 0) return;
    $.each(value.options, function (index, value) {
        var temp_list = [];

        temp_list = $.map(prev_options, function (v, i) {
            return v + ' ' + value;
        });
        return_list = $.merge(return_list, temp_list);
    });

    return_list = $.grep(return_list, function (i) {
        return $.inArray(i, prev_options) == -1;
    });

    prev_options = return_list.slice(0);
});

you can test here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM