【问题标题】:make combinations of two array in json在json中组合两个数组
【发布时间】:2018-07-04 13:57:46
【问题描述】:

输入:

"options": [
  {
    "name": "Color",
    "values": [
      "Blue",
      "Black"
    ]
  },
  {
    "name": "Size",
    "values": [
      "Small",
      "Large"
    ]
  }
]

Output: "variants": [
  {
    "option1": "Blue",
    "option2": "Small"
  },
  {
    "option1": "Blue",
    "option2": "Large"
  },
  {
    "option1": "Black",
    "option2": "Small"
  },
  {
    "option1": "Black",
    "option2": "Large"
  }
]

如何使用递归解决这个问题?选项数组可以包含多个名称,我需要显示以上内容。我猜可以使用笛卡尔积来完成吗

【问题讨论】:

  • options 数组可以包含多个名称 这有什么关系?因为无论如何你在输出中丢失了name

标签: javascript arrays json recursion lodash


【解决方案1】:

您可以使用嵌套的Array.map() 调用、创建对象并使用Array.concat() 展平子数组:

const options = [{"name":"Color","values":["Blue","Black"]},{"name":"Size","values":["155","159"]}]

const [{ values: colors }, { values: sizes }] = options
const result = [].concat(...colors.map((option1) => sizes.map((option2) => ({
  option1,
  option2
}))))

console.log(result)

【讨论】:

  • 二线是如何工作的?这是解构赋值,但看起来很奇怪。
  • 它是数组解构([])中的对象解构({})。
  • 所以基本上你正在分配一个新变量,因为第一个变量已经使用了这个名称?也可能像 var [{ values: colors }, { values:sizes }] = options?
  • 确实-我是assigning to new variable names,确实我可以说出第二个尺寸。我已经更新了示例。
【解决方案2】:

您可以采用迭代和递归的方法来获取所有选项组合。

function getCombinations(array) {

    function iter(i, temp) {
        if (i === array.length) {
            result.push(temp.reduce(function (o, v, i) {
                o['option' + (i + 1)] = v;
                return o;
            }, {}));
            return;
        }
        array[i].values.forEach(function (a) {
            iter(i + 1, temp.concat(a));
        });
    }

    var result = [];
    iter(0, []);
    return result;
}

var options = [{ name: "Color", values: ["Blue", "Black"] }, { name: "Size", values: ["155", "159"] }, { name: 'Material', values: ['Sand', 'Clay', 'Mud'] }],
    variants = getCombinations(options);

console.log(variants);
.as-console-wrapper { max-height: 100% !important; top: 0; }

ES6

function getCombinations(array) {

    function iter(i, temp) {
        if (i === array.length) {
            result.push(temp);
            return;
        }
        array[i].values.forEach(a => iter(i + 1, Object.assign({}, temp, { ['option' + (i + 1)]: a })));
    }

    var result = [];
    iter(0, {});
    return result;
}

var options = [{ name: "Color", values: ["Blue", "Black"] }, { name: "Size", values: ["155", "159"] }, { name: 'Material', values: ['Sand', 'Clay', 'Mud'] }],
    variants = getCombinations(options);

console.log(variants);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 它不适用于以下情况:[{ name: "Color", values: ["Blue", "Black"] }, { name: "Size", values: ["small" ] }, { name: "Material", values: [] }] ... Blue,Small 已创建但没有 Black,Small 组合..实际上 values 数组的元素是动态来的.. 它可以是任意数量甚至是空的......
  • 你期望什么结果?请同时添加完整的options
  • 输出应该是:Blue-Small 和 Black Small .. m 为产品制作变体options= [{ name: "Color", values: ["Blue", "Black"] }, { name: "Size", values: ["Small"] },{ name: "Material", values: [] }] ... options= [{ name: "Color", values: ["Blue", "Black"] }, { name: "Size", values: [] },{ name: "Material", values: ["Cotton"] }].. 这些是一些情况
  • 如果是这样的话,原来应该返回四个组合而不是两个?
  • 这改变了一切。你想得到所有项目的叉积。
【解决方案3】:

var myarray = {"options": [
  {
    "name": "Color",
    "values": [
      "Blue",
      "Black"
    ]
  },
  {
    "name": "Size",
    "values": [
      "155",
      "159"
    ]
  }
]};

const key = myarray.options[0].values;
const value =myarray.options[1].values;
const output = _.zipWith(key, value, (key, value)=> ({ key, value }));
console.log(output);
<script src="https://cdn.jsdelivr.net/lodash/4.16.6/lodash.min.js"></script>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多