简体   繁体   English

如何从对象数组中的嵌套数组中获取数组值的组合

[英]How to get the combination of array values from nested arrays in an array of objects

I have an array of objects with the following structure: 我有一个具有以下结构的对象数组:

 var varientSections = [
  {
    type: "frame",
    values: ["black", "white", "wood"]
  },
  {
    type: "finish",
    values: ["matte", "glossy"]
  }
];

I want to get the combination of the array values and create a new list with it. 我想得到数组值的组合并用它创建一个新列表。 Right now, I am able to retrieve the combination from the nested array values using the method called getCombination(varientSections) . 现在,我可以使用名为getCombination(varientSections)的方法从嵌套数组值中检索组合。 However, I do not know how to create a new list with the following structure: 但是,我不知道如何使用以下结构创建新列表:

var results = [
  {
    attributes: [
      {
        type: "frame",
        value: "black"
      },
      {
        type: "finish",
        value: "matte"
      }
    ]
  },
  {
    attributes: [
      {
        type: "frame",
        value: "black"
      },
      {
        type: "finish",
        value: "glossy"
      }
    ]
  },
  {
    attributes: [
      {
        type: "frame",
        value: "white"
      },
      {
        type: "finish",
        value: "matte"
      }
    ]
  },
  {
    attributes: [
      {
        type: "frame",
        value: "white"
      },
      {
        type: "finish",
        value: "glossy"
      }
    ]
  },
  {
    attributes: [
      {
        type: "frame",
        value: "wood"
      },
      {
        type: "finish",
        value: "matte"
      }
    ]
  },
  {
    attributes: [
      {
        type: "frame",
        value: "wood"
      },
      {
        type: "finish",
        value: "glossy"
      }
    ]
  }
];

Below is my code: 以下是我的代码:

function getCombinations(arr) {
  if (arr.length === 0) {
    return [[]];
  }

  let [current, ...rest] = arr;
  let combinations = getCombinations(rest);

  var result = current.values.reduce(
    (accumulator, currentValue) => [
      ...accumulator,
      ...combinations.map(c => [currentValue, ...c])
    ],
    []
  );
  console.log("result is ");
  console.log(result);
  return result;
}

let varientCombinations = getCombinations(varientSections);
console.log(varientCombinations);

let updatedVarientDetails = [];
varientSections.forEach((varientSection, index) => {
  let type = varientSection.type;
  varientCombinations.forEach(combination => {
    let obj = [
      {
        type: type,
        value: combination[index]
      },
    ];
    updatedVarientDetails.push(obj);
  });
});

console.log(updatedVarientDetails);

You could get the cartesian product and give it later the wanted style. 你可以得到笛卡尔积,然后给它想要的风格。 The names and values are taken form the handed over object. 名称和值来自移交对象。

The algorithm takes all key/value pairs and has a stric view to the values, that means if an array is found or an object, hence w && typeof w === "object" , the actual part is taken an used for adding additional key/value pairs. 该算法采用所有键/值对并具有值的严格视图,这意味着如果找到数组或对象,因此w && typeof w === "object" ,实际部分用于添加额外的键/值对。

For example a small object with two properties 例如,具有两个属性的小对象

{ a: 1, b: [2, 3] }

yields 产量

[
    { a: 1, b: 2 },
    { a: 1, b: 3 }
]

A bit more advanced object, like 更高级的对象,比如

{ a: 1, b: { c: { d: [2, 3], e: [4, 5] } } }

yields the same structure as given 产生与给定相同的结构

[
    {
        a: 1,
        b: {
            c: { d: 2, e: 4 }
        }
    },
    {
        a: 1,
        b: {
            c: { d: 2, e: 5 }
        }
    },
    {
        a: 1,
        b: {
            c: { d: 3, e: 4 }
        }
    },
    {
        a: 1,
        b: {
            c: { d: 3, e: 5 }
        }
    }
]

Thant means, from any found sub object the cartesian product is taken and combined with the actual values. Thant意味着,从任何找到的子对象中获取笛卡尔积并将其与实际值组合。

 const getCartesian = object => Object.entries(object).reduce( (r, [key, value]) => { let temp = []; r.forEach(s => (Array.isArray(value) ? value : [value]).forEach(w => (w && typeof w === "object" ? getCartesian(w) : [w]).forEach(x => temp.push({ ...s, [key]: x }) ) ) ); return temp; }, [{}] ), data = [{ type: "frame", value: ["black", "white", "wood"] }, { type: "finish", value: ["matte", "glossy"] }], result = getCartesian(data) .map(o => ({ attributes: Object.assign([], o).map(({ ...o }) => o) })); console.log(result); console.log(getCartesian({ a: 1, b: { c: { d: [2, 3], e: [4, 5] } } })); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

You could simplify it to this: 你可以简化它:

 var variantSections = [ { type: "frame", values: ["black", "white", "wood"] }, { type: "finish", values: ["matte", "glossy"] } ]; // iterate through each variantSection and create objects like {"type": "frame", "value": "black"} var sections = variantSections.map(variant => { return variant.values.map(val => ({type: variant.type, value: val})) }); // then iterate through the two resulting arrays of objects, combining each into the attributes object you want var results = []; for (var i = 0; i < sections[0].length; i++) { for (var j = 0; j < sections[1].length; j++) { results.push({attributes: [sections[0][i], sections[1][j]]}); } } console.log(JSON.parse(JSON.stringify(results))); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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