首页 > 解决方案 > 根据对象属性将多个数组组合为一个

问题描述

我正在做一个电子商务网站。我必须管理产品变化。REST API 响应如下所示:

"variations": [
  {
    "attributeCombinations": [
      {
        "name": "Color",
        "valueName": "GRIS"
      },
      {
        "name": "Talle",
        "valueName": "L"
      }
    ]
  },
  {
    "attributeCombinations": [
      {
        "name": "Color",
        "valueName": "GRIS"
      },
      {
        "name": "Talle",
        "valueName": "XXL"
      }
    ]
  },
  {
    "attributeCombinations": [
      {
        "name": "Color",
        "valueName": "Azul"
      },
      {
        "name": "Talle",
        "valueName": "M"
      }
    ]
  },
  {
    "attributeCombinations": [
      {
        "name": "Color",
        "valueName": "GRIS"
      },
      {
        "name": "Talle",
        "valueName": "S"
      }
    ]
  },
  {
    "attributeCombinations": [
      {
        "name": "Color",
        "valueName": "GRIS"
      },
      {
        "name": "Talle",
        "valueName": "XL"
      }
    ]
  },
  {
    "attributeCombinations": [
      {
        "name": "Color",
        "valueName": "Azul"
      },
      {
        "name": "Talle",
        "valueName": "S"
      }
    ]
  },
  {
    "attributeCombinations": [
      {
        "name": "Color",
        "valueName": "GRIS"
      },
      {
        "name": "Talle",
        "valueName": "M"
      }
    ]
  }
]

这个 JSON 对我在前端工作来说效率很低。很难根据其类型(名称)和值(值名称)对变体进行分组,因为它们位于不同的“数组数组”上。

最终结果应该是这样的:

variations: [
  {
    name: 'Color',
    values: ['Gris', 'Azul']
  },
  {
    name: 'Talle',
    values: ['S', 'M', 'L', 'XL', 'XXL']
  }
]

到目前为止,我已经取得了这个结果:

[
  { name: "Color", values: ["GRIS"] },
  { name: "Talle", values: ["L"] },
  { name: "Color", values: ["GRIS"] },
  { name: "Talle", values: ["XXL"] },
  { name: "Color", values: ["Azul"] },
  { name: "Talle", values: ["M"] },
  { name: "Color", values: ["GRIS"] },
  { name: "Talle", values: ["S"] },
  { name: "Color", values: ["GRIS"] },
  { name: "Talle", values: ["XL"] },
  { name: "Color", values: ["Azul"] },
  { name: "Talle", values: ["S"] },
  { name: "Color", values: ["GRIS"] },
  { name: "Talle", values: ["M"] }
]

基于此代码:

let variations = this.$page.product.variations;
let newArr = [];

variations.forEach(variation => {
        newArr.push(
          Object.values(
            variation.attributeCombinations.reduce(
              (result, { name, valueName }) => {
                // Create new group
                if (!result[name]) {
                  result[name] = {
                    name,
                    values: []
                  };
                }
                // Append to group
                result[name].values.push(valueName);

                return result;
              },
              {}
            )
          )
        );
      });
return newArr.reduce((acc, cur) => acc.concat(cur));

标签: javascriptarraysobjectecmascript-2016

解决方案


您可以使用reduce循环遍历数组并汇总到一个对象中。用于forEach循环attributeCombinations并构造所需的输出。用于Object.values将对象转换为数组。

var variations = [{"attributeCombinations":[{"name":"Color","valueName":"GRIS"},{"name":"Talle","valueName":"L"}]},{"attributeCombinations":[{"name":"Color","valueName":"GRIS"},{"name":"Talle","valueName":"XXL"}]},{"attributeCombinations":[{"name":"Color","valueName":"Azul"},{"name":"Talle","valueName":"M"}]},{"attributeCombinations":[{"name":"Color","valueName":"GRIS"},{"name":"Talle","valueName":"S"}]},{"attributeCombinations":[{"name":"Color","valueName":"GRIS"},{"name":"Talle","valueName":"XL"}]},{"attributeCombinations":[{"name":"Color","valueName":"Azul"},{"name":"Talle","valueName":"S"}]},{"attributeCombinations":[{"name":"Color","valueName":"GRIS"},{"name":"Talle","valueName":"M"}]}];

var result = Object.values(variations.reduce((c, v) => {
  v.attributeCombinations.forEach(({name,valueName}) => {
    c[name] = c[name] || {name,values: []}
    c[name].values.push(valueName);
  });
  return c;
}, {}));

console.log(result);


如果您想要唯一值,您可以使用Set并添加另一个循环将Set对象转换为数组。

var variations = [{"attributeCombinations":[{"name":"Color","valueName":"GRIS"},{"name":"Talle","valueName":"L"}]},{"attributeCombinations":[{"name":"Color","valueName":"GRIS"},{"name":"Talle","valueName":"XXL"}]},{"attributeCombinations":[{"name":"Color","valueName":"Azul"},{"name":"Talle","valueName":"M"}]},{"attributeCombinations":[{"name":"Color","valueName":"GRIS"},{"name":"Talle","valueName":"S"}]},{"attributeCombinations":[{"name":"Color","valueName":"GRIS"},{"name":"Talle","valueName":"XL"}]},{"attributeCombinations":[{"name":"Color","valueName":"Azul"},{"name":"Talle","valueName":"S"}]},{"attributeCombinations":[{"name":"Color","valueName":"GRIS"},{"name":"Talle","valueName":"M"}]}]

var result = Object.values(variations.reduce((c, v) => {
  v.attributeCombinations.forEach(({name,valueName}) => {
    c[name] = c[name] || {name,values: new Set}
    c[name].values.add(valueName);
  });
  return c;
}, {})).map(o => {
  o.values = [...o.values.values()]
  return o;
});

console.log(result);


推荐阅读