如何组合多个数组中的值以创建新的组合数组

时间:2020-12-03 12:56:02

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.

在每个类型中,我还允许用户配置多个选项。例如,类型Size可能有Small,Medium,Large选项。用户再次可以定义这些字段的名称,并且不应对他们可以创建的字段数量进行任何限制。

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:

根据这些数据,我想创建18(3 * 2 * 3)种可能的产品变体,用户可以为其指定特定的价格,重量或SKU选项。最终得到以下变体:

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.

我的问题是我如何创建一个循环,允许我迭代各种类型和选择来创建我的最终变体列表?我很难想象我如何才能提供这个功能。

2 个解决方案

#1


1  

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.

请尝试以下代码。它完全符合你想要的纯JavaScript。 generateOutput函数在循环中为第一个元素的选项调用,然后generateOutput函数被称为递归生成所需的结果。写作中的逻辑难以解释。只需添加调试器并了解流程。祝你好运。

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());

#2


0  

here is some jquery code using various jquery array methods

这里是一些使用各种jquery数组方法的jquery代码

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

你可以在这里测试一下

#1


1  

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.

请尝试以下代码。它完全符合你想要的纯JavaScript。 generateOutput函数在循环中为第一个元素的选项调用,然后generateOutput函数被称为递归生成所需的结果。写作中的逻辑难以解释。只需添加调试器并了解流程。祝你好运。

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());

#2


0  

here is some jquery code using various jquery array methods

这里是一些使用各种jquery数组方法的jquery代码

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

你可以在这里测试一下