如何在合并其中一个字段的同时减少数组

问题描述 投票:1回答:6

我有这个,

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条记录,但这只是一个例子。

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

javascript
6个回答
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);

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
投票

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

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

0
投票

function merge(array, key = 'id') {
  const obj = {}
  
  for(const item of array) {
    const existing = obj[item[key]]
    if(existing) {
      for(const [name, value] of Object.entries(item)) {
        if(name === key) continue;
        
        if(existing[name]) {
          existing[name] = [ ...(existing[name].$custom ? existing[name] : [existing[name]]), value ]
          existing[name].$custom = true;
        } else {
          existing[name] = value;          
        }
      }
    } else {
      obj[item[key]] = { ...item }
    }
  }
  
  return Object.values(obj)
}

var o = [
{
  "id": 1,
  "single": "test"
},
{
  "id": 1,
  "course": "name1",
  "multifield": "test"
}, 
{
  "id": 1,
  "course": "name2"
},
{
  "id": 1,
  "newfield": "test"
}, {
  "id": 2,
  "anotherid": "test",
  "array": [1,3,4]
}, {
  "id": 2,
  "array": "text"
}];

console.log(merge(o))

0
投票

您可以使用reduce来累积结果。在当前结果(累加器a)中搜索具有相同id的对象(el),如果找到,则将路线附加到现有对象并返回相同的累加器,否则将course作为数组放入累加器。

var res = o.reduce((a, {id,course}) => {
    var found = a.find(el => el.id == id);
    return found ? found.course.push(course) && a : [...a, {id, course: [course]}];
}, []);
© www.soinside.com 2019 - 2024. All rights reserved.