如何在合并一个字段的同时缩小数组

时间:2019-03-12 11:56:02

标签: javascript

我有这个

var o = [{
  "id": 1, // its actually a string in real life
  "course": "name1",
  // more properties
}, 
{
  "id": 1, // its actually a string in real life
  "course": "name2",
  // more properties
}];

我想要这个

var r = [{
  "id": 1, // its actually a string in real life
  "course": ["name1", "name2"],
}];

我正在尝试这个,

var flattened = [];
for (var i = 0; i < a.length; ++i) {
  var current = a[i];
  if(flattened.)
}

但是我被困住了,我不确定下一步该怎么做,数组将有2条以上的记录,但这只是一个例子。

还有更多字段,但为简单起见我将其删除,我不会在最终数组中使用它们。

4 个答案:

答案 0 :(得分:4)

您可以缩小数组并找到对象。

var array = [{ id: 1, course: "name1" }, { id: 1, course: "name2" }],
    flat = array.reduce((r, { id, course }) => {
        var temp = r.find(o => id === o.id);
        if (!temp) {
            r.push(temp = { id, course: [] });
        }
        temp.course.push(course);
        return r;
    }, []);

console.log(flat);

使用Map也是如此。

var array = [{ id: 1, course: "name1" }, { id: 1, course: "name2" }],
    flat = Array.from(
        array.reduce((m, { id, course }) => m.set(id, [...(m.get(id) || []) , course]), new Map),
        ([id, course]) => ({ id, course })
    );

console.log(flat);

答案 1 :(得分:1)

通过这种方式,您可以将数据展平为所需的形状

const o = [
  {
    id: 1,
    course: "name1"
  },
  {
    id: 1,
    course: "name2"
  },
  {
    id: 2,
    course: "name2"
  }
];

const r = o.reduce((acc, current) => {
  const index = acc.findIndex(x => x.id === current.id);
  if (index !== -1) {
    acc[index].course.push(current.course);
  } else {
    acc.push({id:current.id, course: [current.course]});
  }
  return acc
}, []);

console.log(r);

答案 2 :(得分:1)

您可以使用.reduce创建密钥的对象,然后使用该对象将密钥设置为id的密钥。这样,您可以通过定位对象的course来添加到同一id数组中。最后,您可以获取对象的值以获取结果。

请参见以下示例:

var o = [{
  "id": 1,
  "course": "name1",
  "foo": 1
}, 
{
  "id": 1,
  "course": "name2",
  "bar": 2
}];

var res = Object.values(o.reduce((acc, {id, course, ...rest}) => {
  if(id in acc) 
    acc[id] = {...acc[id], course: [...acc[id].course, course], ...rest};
  else acc[id] = {id, course: [course], ...rest};
  return acc;
}, {}));

console.log(res);

答案 3 :(得分:1)

您可以使用reduceObject.entries进行此操作。此示例适用于任意数量的属性:

const o = [
  { id: 1, course: 'name1', time: 'morning', topic: 'math' },
  { id: 1, course: 'name2', time: 'afternoon' },
  { id: 2, course: 'name3', time: 'evening' }
];

const result = o.reduce((out, { id, ...rest }) => {
  out[id] = out[id] || {};
  const mergedProps = Object.entries(rest).reduce((acc, [k, v]) => {
    return { ...acc, [k]: [...(out[id][k] || []), v] };
  }, out[id]);
  out[id] = { id, ...mergedProps };
  return out;
}, {});

console.log(result);

如果您只关心idcourse字段,则可以简化为:

const o = [
  { id: 1, course: 'name1', time: 'morning', topic: 'math' },
  { id: 1, course: 'name2', time: 'afternoon' },
  { id: 2, course: 'name3', time: 'evening' }
];

const result = o.reduce((out, { id, course }) =>
  ({ ...out, [id]: { id, course: [...((out[id] || {}).course || []), course] } })
, {});

console.log(result);