javascript中的数组交叉循环

时间:2017-10-17 06:05:26

标签: javascript arrays ecmascript-6

让我说我有这个代码:

        // If no match was found, return this
        if (off == 0)
            return new String[]{this};

        // Add remaining segment
        if (!limited || list.size() < limit)
            list.add(substring(off, value.length));

好的,现在我该如何输出它:

enter image description here

并且let variants = [] let variant = { variantName: 'Size', variantItems: ['XL','MD','SM'] } variants.push(variant) variant = { variantName: 'Color', variantItems: ['Red','Blue'] } variants.push(variant) 数组可以包含许多variants对象

如果variant数组中还有一个对象:

variants

它会像这样输出:

enter image description here

请帮助,非常感谢您的帮助...

3 个答案:

答案 0 :(得分:2)

您可以使用Array#mapArray#concat的递归函数来展平结果:

&#13;
&#13;
const variants = [{"variantName":"Size","variantItems":["XL","MD","SM"]},{"variantName":"Color","variantItems":["Red","Blue"]},{"variantName":"Material","variantItems":["Plastic","Wood","Ceramic"]}];

const addVariants = (variants) => {
  // destructure the 1st item array, and the rest of the variants
  const add = ([{ variantName, variantItems }, ...variants], row = []) => 
    // iterate the variants and flatten
    [].concat(...variantItems.map((variantItem) => {
      // create a new array for the current row, and the variant string
      const currRow = [...row, `${variantName}: ${variantItem}`];

      // if there are more variants, invoke add with the remaining variants and the current row, or join the array to a string (the end result)
      return variants.length ? add(variants, currRow) : currRow.join(', '); // instead of currRow.join(', ') replace with [currRow] if you want an array
    }));

  return add(variants);
}

const result = addVariants(variants);

console.log(result);
&#13;
&#13;
&#13;

答案 1 :(得分:1)

这是一种功能强大的ES6方法。

&#13;
&#13;
let variants = [{
    variantName: "Size",
    variantItems: [
      "XL",
      "MD",
      "SM"
    ]
  },
  {
    variantName: "Color",
    variantItems: [
      "Red",
      "Blue"
    ]
  }];

let crossJoined = new Array(variants.reduce((product, variant) => (product * variant.variantItems.length), 1))
  .fill(0)
  .reduce(crossJoin => {
    crossJoin.data.push(crossJoin.currentIndexes.map((itemIndex, variantIndex) => `${variants[variantIndex].variantName}: ${variants[variantIndex].variantItems[itemIndex]}`).join(", "));

    let incrementableIndex = variants.length - crossJoin.currentIndexes
      .slice()
      .reverse()
      .findIndex((itemIndex, variantIndex) => variants[variants.length - variantIndex - 1].variantItems.length > itemIndex + 1) - 1;

    crossJoin.currentIndexes[incrementableIndex]++;
    crossJoin.currentIndexes = crossJoin.currentIndexes.map((value, index) => (index > incrementableIndex
      ? 0
      : value));
    
    return (crossJoin.currentIndexes.length == variants.length
      ? crossJoin
      : crossJoin.data);
  }, {
    data: [],
    currentIndexes: new Array(variants.length).fill(0)
  }).join("\n");

console.log(crossJoined);
&#13;
&#13;
&#13;

首先,创建一个数组,其长度为所有variantItems个数组长度,然后填充为零。接下来,我们reduce到另一个数组。

crossJoin是聚合器,它在大多数时间保存此结构的对象:

{
  data: [ … ],
  currentIndexes: [ 1, 3 ] // Corresponds to variants[0].variantItems[1]
                           //            and variants[1].variantItems[3]
}

这是“大部分时间”,直到最后,currentIndexes将不再使用,而将返回其data属性。

因此,在每个reduce次迭代中,我们首先使用crossJoin.data和该数组的索引将新条目推送到crossJoin.currentIndexes。删除.join(", ")将导致结构的输入

[ "Size", "XL" ]

接下来,我们需要增加crossJoin.currentIndexes中的数字:

[ 0, 0 ]应增加到[ 0, 1 ],因为索引1处有第二种颜色。 [ 0, 1 ]应增加到[ 1, 0 ],因为没有第三种颜色,但是第二种颜色,但我们需要再次使用第一种颜色,依此类推。最后一个有效索引数组是[ 2, 1 ],它对应于第三个大小,第二个颜色是最后一个组合。

incrementableIndex是最后一个可以递增的索引。一旦递增,所有后续索引必须为0

您会看到variants.length - 某些内容 - 1两次,因为您需要从结尾中找到第一个索引,因此您必须{ {1}}( 的副本 - 因此reverse)数组,然后再次将找到的索引重新解释为索引。

slice返回此return对象以进行下一次迭代。条件crossJoin适用于最终,其中没有索引可以再增加。它会向crossJoin.currentIndexes.length == variants.length数组添加NaN,因此长度不匹配,而不是过滤掉或阻止currentIndexes,我只是忽略并完全丢弃它。

输出将是所有组合的数组。您可以NaN创建一个字符串,其中每个组合由换行符分隔,或者您可以使用.join("\n")将每个组合附加到列表中,例如。

答案 2 :(得分:0)

在variants数组上使用.each循环。使用另一个数组并使用大小,颜色和材质添加对象。所以它将成为您需求的组合数组。然后使用.each循环按照要求打印新的数组数据。