javascript 查找数组中对象的公共元素并将其分组

to94eoyn  于 2023-02-21  发布在  Java
关注(0)|答案(2)|浏览(119)

我试图弄清楚如何Map一个新的对象数组,通过检查每个用户数组,并在存在公共用户的情况下,将整个数组移动到一个新属性中,该属性也具有公共的notebookId,从而创建团队。
我有一个对象数组,结构如下:

const usersByNotebooks = 
[
{
    "notebookId": "abc",
    "users": [1, 2, 3, 4]
  },
  {
    "notebookId": "cde",
    "users": [2, 3, 4]
  },
  {
    "notebookId": "fgh",
    "users": [3, 4, 5]
  },
  {
    "notebookId": "qqq",
    "users": [33, 16, 12]
  },
]

因此,对于上面的数据,它将变成这样:

const teams = 
[
{
    "notebooksOnTeam": ["abc", "cde", "fgh"],
    "usersOnTeam": [1, 2, 3, 4, 5]
  },
  {
    "notebooksOnTeam": "qqq",
    "usersOnTeam": [33, 16, 12]
  },
]

我正在使用javascript,很难把逻辑写下来。

fwzugrvs

fwzugrvs1#

  • 使用reduce在数组对象上循环并检查:
  • 如果当前笔记本的用户与find方法中的任何现有团队都不匹配,则创建一个新团队。
  • 如果当前笔记本的用户与现有团队匹配,则将笔记本添加到该团队。
const usersByNotebooks = [{ "notebookId": "abc", "users": [1, 2, 3, 4] }, { "notebookId": "cde", "users": [2, 3, 4] }, { "notebookId": "fgh", "users": [3, 4, 5] }, { "notebookId": "qqq", "users": [33, 16, 12] }, ]; 
const teams = usersByNotebooks.reduce((result, current) => {
  const teamFound = result.find((team) => team.usersOnTeam.some((user) => current.users.includes(user)));

  if (!teamFound) {
    result.push({
      notebooksOnTeam: [current.notebookId],
      usersOnTeam: current.users
    });
  } else {
    teamFound.notebooksOnTeam.push(current.notebookId);
    current.users.forEach((user) => {
      if (!teamFound.usersOnTeam.includes(user)) {
        teamFound.usersOnTeam.push(user);
      }
    });
  }
  return result;
}, []);
console.log(teams)
oxalkeyp

oxalkeyp2#

您可以查看结果集中的任何对象,然后获取同一组的第一个对象,并添加所有其他找到的对象,最后添加实际值,或者稍后添加新对象。
这种方法适用于未排序和未连接的项目,这些项目稍后会得到一个关节。

const
    addIfNotExist = (array, value) => array.includes(value) || array.push(value),
    usersByNotebooks = [{ notebookId: "abc", users: [1, 2, 3, 4] }, { notebookId: "cde", users: [2, 3, 4] }, { notebookId: "fgh", users: [3, 4, 5] }, { notebookId: "qqq", users: [33, 16, 12] }, { notebookId: "xxx", users: [6, 7] }, { notebookId: "yyy", users: [5, 6] }],
    result = usersByNotebooks.reduce(
        (r, { notebookId, users }) => users.reduce((s, user) => {
            const objects = [];
            let first;
            for (const o of s) {
                if (!o.users.includes(user) && !o.notebooks.includes(notebookId)) {
                    objects.push(o);
                    continue;
                }
                if (!first) objects.push(first = o);

                o.users.forEach(addIfNotExist.bind(null, first.users));
                o.notebooks.forEach(addIfNotExist.bind(null, first.notebooks));
            }

            if (first) {
                addIfNotExist(first.users, user);
                addIfNotExist(first.notebooks, notebookId);
            } else {
                objects.push({ users: [user], notebooks: [notebookId] });
            }
            return objects;
        }, r),
        []
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

这是一个抽象的解决办法,任何长度的团体是连通的。
它分三步工作:

  • 生成元组中的对或更多或更少项的数组,
  • 将连接的项组合在一组数组中,以及
  • 以所需格式Map项目。

一个二个一个一个

相关问题