根据对象属性将多个数组分组为一个

Group many arrays into one based on object properties

我在电子商务网站上工作。我必须管理产品变体。 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 对我来说在前端工作效率很低。很难根据类型(名称)和值(valueName)对变体进行分组,因为它们位于不同的 "array of arrays".

最终结果应该是这样的:

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

您可以使用 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);

您可以使用函数 reduce 进行分组,使用函数 Object.values 提取值。

对象 Set 提供了一种删除重复值的方法。

let 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"       }     ]   } ];
let result = Object.values(variations.reduce((a, {attributeCombinations: combinations}) => {
  combinations.forEach(({name, valueName}) => {
    (a[name] || (a[name] = {name, values: new Set()})).values.add(valueName);
  });
  
  return a;
}, {}));

console.log(Array.from(result[0].values));// for understanding the object set
console.log(result);
.as-console-wrapper { min-height: 100%; }

为了达到预期的结果,请使用以下选项使用 reduce 、 forEach 和每个循环的索引

  1. 遍历变体数组
  2. 对于位置 0 的第一个索引,推送到累加器 (acc)
  3. 使用 .forEach 使用第二个循环遍历 attributeCombinations
  4. 将 valueNames 推送到相应的名称 - Color 和 Talle

var arr = {"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"
      }
    ]
  }
]
          }


console.log(arr.variations.reduce((acc, val, idx) => {
  val.attributeCombinations.forEach((v, i) => {
  if(idx === 0) {
    acc.push({name: v.name , valueName:  Array.of(v.valueName)})
  }else{
    i === 0 ? acc[0].valueName.push(v.valueName) : acc[1].valueName.push(v.valueName) 
  }
})
  return acc
},[]).map(v => v = {name :v.name,  valueName: [...new Set(v.valueName)]}));

codepen - https://codepen.io/nagasai/pen/ZZxVzp?editors=1010