获取对象数组中重复键的值

时间:2018-04-23 13:13:06

标签: javascript arrays algorithm loops sorting

我有一个像这样的对象数组。我想摆脱重复的密钥(名称),只有一个名称,其中包含数组中所有相关的值。

let array = [ 
  { name: "dimensions", value: "dimensions value 1" },
  { name: "weight",     value: "weight value 1" },
  { name: "dimensions", value: "dimensions value 2" },
  { name: "weight",     value: "weight value 3" },
  { name: "dimensions", value: "dimensions value 3" },
  { name: "weight",     value: "weight value 3" } 
]

我想把它变成这样的东西:

result = [ {
  name : "dimensions", 
  values : ["dimention value 1", "dimention value 2", "dimention value 3"] 
    }, {
  name : "weights", 
  values : ["weight value 1", "weight value 2", "weight value 3"] 
} ]

注意:数组中对象的计数是可变的。 "体重","尺寸","颜色","品牌"等...

我到目前为止所尝试的内容:

let flags = [], output = [], l = array.length;

for (let i = 0; i < l; i++) {
    if (flags[array[i].name])
      continue;

    flags[array[i].name] = array[i].name;

    output.push({
        name : array[i].name,
        values : [array[i].value]
    });
}

它返回的内容如下:

[
  { name: "dimensions", values: [ "dimensions value 1"] },
  { name: "weight",     values: [ "weight value 1"] }
]
let array = [
  { name: "dimensions", value: "dimensions value 1" },
  { name: "weight",     value: "weight value 1"},
  { name: "dimensions", value: "dimensions value 2"},
  { name: "weight",     value: "weight value 3"},
  { name: "dimensions", value: "dimensions value 3"},
  { name: "weight",     value: "weight value 3" }
]

let flags = [], output = [], l = array.length;

for (let i = 0; i < l; i++) {
  if (flags[array[i].name])
    continue;

  flags[array[i].name] = array[i].name;

  output.push({
    name: array[i].name,
    values: [array[i].value]
  });
}

console.log(output);

3 个答案:

答案 0 :(得分:5)

您可以array#reduce使用Object.values()根据name对数组进行分组。

&#13;
&#13;
let array = [ {name: "dimensions", value: "dimensions value 1"}, {name: "weight", value: "weight value 1"}, {name: "dimensions", value: "dimensions value 2"}, {name: "weight", value: "weight value 3"}, {name: "dimensions", value: "dimensions value 3"},{name: "weight", value: "weight value 3"} ],
  result = Object.values(array.reduce((r,{name, value}) => {
    r[name] = r[name] || {name, values : []};
    r[name].values.push(value);
    return r;
  },{}));
console.log(result);
&#13;
&#13;
&#13;

答案 1 :(得分:3)

您可以使用ES6 Map来存储值,然后使用扩展语法...来获取对象数组中的值。

let array = [ {name: "dimensions", value: "dimensions value 1"},{name: "weight", value: "weight value 1"},{name: "dimensions", value: "dimensions value 2"},{name: "weight", value: "weight value 3"},{name: "dimensions", value: "dimensions value 3"},{name: "weight", value: "weight value 3"} ]

const map = array.reduce((r, {name, value}) => {
  if(!r.has(name)) r.set(name, {name, values: [value]});
  else r.get(name).values.push(value)
  return r;
}, new Map);

const result = [...map.values()];
console.log(result)

答案 2 :(得分:0)

虽然其他答案产生了您想要的输出,但可能会更容易使用键,其中键是&#34;尺寸&#34;和&#34;权重&#34;它们的值是字符串数组。您可以使用稍微简单的reduce

来实现
const out = array.reduce((p, c) => {
  p[c.name] = p[c.name] || [];
  p[c.name].push(c.value);
  return p;
}, {});

输出

{
  "dimensions": [
    "dimensions value 1",
    "dimensions value 2",
    "dimensions value 3"
  ],
  "weight": [
    "weight value 1",
    "weight value 3",
    "weight value 3"
  ]
}

这只是意味着您现在可以访问属性:

out.dimensions[0]

而不是

out[0].values

这对imo来说不那么有用。