数组转换问题?

我有下面的形式的数组

[{
   id: 1,
   name: 1,
   port: 1,
   unit: 2
}, {
  id: 2,
  name: 2,
  port: 3,
  unit: 4
}]

我想根据id和name对其进行分组,得到下面形式的数组,代码要如何编写?

[{
  id: 1,
  name: 1,
  ports: [
    {
       port: 1, unit: 2
    }
  ]
},{
  id: 2,
  name: 2,
  ports: [
    {
       port: 3, unit: 4
    }
  ]
}]
阅读 2.5k
6 个回答
let arr = [{
   id: 1,
   name: 1,
   port: 1,
   unit: 2
}, {
  id: 2,
  name: 2,
  port: 3,
  unit: 4
}]

let res = [], obj = {}
arr.forEach(item => {
    let key = item.id + '-' + item.name
    let target = {port: item.port, unit: item.unit}
    if(!obj[key]){
        res.push(obj[key] = {
          id: item.id,
          name: item.name,
          ports: [target]
        })
    }else{
        obj[key].ports.push(target)
    }
})

console.log(res)
var data = [
  { id: 1, name: 1, port: 1, unit: 2 },
  { id: 2, name: 2, port: 3, unit: 4 }
];

var groupedData = data.reduce((accumulator, current) => {
  // 查找是否已经存在相同的分组
  var existingGroup = accumulator.find(group => group.id === current.id && group.name === current.name);

  if (existingGroup) {
    // 如果已存在相同的分组,则将当前对象的 'port' 和 'unit' 添加到该分组的 'ports' 数组中
    existingGroup.ports.push({ port: current.port, unit: current.unit });
  } else {
    // 如果不存在相同的分组,则创建一个新的分组对象,并初始化 'ports' 数组
    accumulator.push({
      id: current.id,
      name: current.name,
      ports: [{ port: current.port, unit: current.unit }]
    });
  }

  return accumulator;
}, []);

console.log(groupedData);

如果对数据处理不熟悉,可以直接使用 Lodash,提供了 groupBy 函数用于分组。
分组的时候需要找到每个对象对应的关键字(分组依据),如果 idname 是一一对应关系,只需要按 id 或者 name 分组即可

_.groupBy(list, it => it.id);

如果 idname 不是一一对应,而是存在组合,比如存在 { id: 1, name: 1}{ id: 1, name: 2 }{ id: 2, name: 1} 等情况,那需要把 idname 组成一个 KEY 来分组,比如

_.groupBy(list, it => `${it.id}|${it.name}`);

完整的程序如下

const result = _(list)
    .groupBy(it => `${it.id}|${it.name}`)
    .values()
    .map(its => ({
        id: its[0].id,
        name: its[0].name,
        ports: its.map(({ port, unit }) => ({ port, unit }))
    }))
    .value();

console.log(result);

如果自己写分组,可以在分组的同时处理数据,

const result = Object.values(
    list.reduce((group, { id, name, ...portInfo }) => {
        const key = `${id}|${name}`;
        (group[key] ??= { id, name, ports: [] }).ports.push(portInfo);
        return group;
    }, {})
);

console.dir(result, { depth: null });

好像回答过不少关于分组的问题,随便搜就搜出来一堆,给几个参考

1.用 reduce 方法:

let arr = [{
   id: 1,
   name: 1,
   port: 1,
   unit: 2
}, {
  id: 2,
  name: 2,
  port: 3,
  unit: 4
}]

let res = arr.reduce((acc, cur) => {
    let found = acc.find(item => item.id === cur.id && item.name === cur.name);
    if (found) {
        found.ports.push({port: cur.port, unit: cur.unit});
    } else {
        acc.push({
            id: cur.id,
            name: cur.name,
            ports: [{port: cur.port, unit: cur.unit}]
        });
    }
    return acc;
}, []);

console.log(res);

2.用 Map 对象:

let arr = [{
   id: 1,
   name: 1,
   port: 1,
   unit: 2
}, {
  id: 2,
  name: 2,
  port: 3,
  unit: 4
}]

let map = new Map();
arr.forEach(item => {
    let key = `${item.id}-${item.name}`;
    let value = map.get(key);
    if (value) {
        value.ports.push({port: item.port, unit: item.unit});
    } else {
        map.set(key, {
            id: item.id,
            name: item.name,
            ports: [{port: item.port, unit: item.unit}]
        });
    }
});

let res = Array.from(map.values());

console.log(res);
let tere = arr.map(({ id, name, port, unit }) => ({
  id,
  name,
  ports: [{ port, unit }],
}));

您可以使用 JavaScript 中的 reduce 方法来实现这个功能。reduce 方法接受一个函数作为参数,该函数接受两个参数:累加器和当前元素。在这个函数中,您可以根据 id 和 name 将元素添加到正确的组中。

以下是一个实现此功能的示例代码:

const arr = [
  { id: 1, name: 1, port: 1, unit: 2 },
  { id: 2, name: 2, port: 3, unit: 4 }
];

const result = arr.reduce((acc, curr) => {
  const { id, name, port, unit } = curr;
  const existingItemIndex = acc.findIndex(item => item.id === id && item.name === name);
  if (existingItemIndex >= 0) {
    acc[existingItemIndex].ports.push({ port, unit });
  } else {
    acc.push({ id, name, ports: [{ port, unit }] });
  }
  return acc;
}, []);

console.log(result);
// Output: [{ id: 1, name: 1, ports: [{ port: 1, unit: 2 }] }, { id: 2, name: 2, ports: [{ port: 3, unit: 4 }] }]

在上面的示例中,我们首先使用 reduce 方法初始化一个空数组作为累加器。然后,我们遍历数组中的每个元素,从当前元素中获取 id、name、port 和 unit 属性。我们使用 findIndex 方法查找累加器中是否已经存在具有相同 id 和 name 的元素。如果找到了这样的元素,则将当前元素的 port 和 unit 属性添加到该元素的 ports 数组中。否则,我们将创建一个新的对象,该对象包含 id、name 和 ports 属性,并将其添加到累加器中。最后,我们返回累加器。

在上面的示例中,我们使用 console.log 输出了结果,输出如下所示:

[{ id: 1, name: 1, ports: [{ port: 1, unit: 2 }] }, { id: 2, name: 2, ports: [{ port: 3, unit: 4 }] }]

以上内容由 AI 生成
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题