Построить дерево из плоского массива, используя две таблицы данных в Javascript - PullRequest
0 голосов
/ 25 июня 2018

Я застрял с созданием древовидной структуры из плоского массива, используя две таблицы данных Mock в JSON.таблица должна соответствовать двум уникальным идентификаторам для определения иерархии между ними.

JSON с массивом БД групп выглядит так:

 {
"group": [
    {
        "groupName": "ROOT",
        "id": 1
    },
    {
        "groupName": "Family",
        "id": 9
    },
    {
        "groupName": "BestFriends!",
        "id": 10
    },
     {
        "groupName": "Cars",
        "id": 4
    },
      {
        "groupName": "funHouse",
        "id": 3
    }

]
 };

JSON, включаяМассив пользователей выглядит так:

 {
"user": [
    {
        "username": "StrongGoose",
        "password": "sdff12fdsa",
        "age": 31,
        "id": 2
    },
    {
        "username": "John",
        "password": "sdjd34fffdsa",
        "age": 31,
        "id": 3
    },
    {
        "username": "Mary",
        "password": "sdfffdsa",
        "age": 31,
        "id": 4
    }
]
 };

так выглядит первая таблица данных и определяет иерархию между группами:

 {
"GroupsToGroups": [
    {
        "1":[9,10]
    },
    {
        "10":[3]
    }

]
 };

Второй выглядит так и определяет, к какому пользователю относится какая группа:

 {
"GroupsToUsers": [
    {
        "11":[2]
    },
    {
        "3":[3]
    },
    {
        "4":[4]
    },
    {
    "10":[2] 
    },
    {
    "3":[3] 
    }
   ]
  };

Иерархия должна выглядеть так, должна быть записана в JSON

 [
{
    "type": "group",
    "id": "1",
    "name": "ROOT",
    "items": [
        {
            "type": "group",
            "id": "9",
            "name": "Family",
            "items": []
        },
        {
            "type": "group",
            "id": "10",
            "name": "BestFriends!",
            "items": [
                {
                    "username": "StrongGoose",
                    "password": "sdff12fdsa",
                    "age": 31,
                    "id": 2
                },

                {
                    "type": "group",
                    "id": "3",
                    "name": "funHouse",
                    "items": [
                        {
                            "username": "John",
                            "password": "sdjd34fffdsa",
                            "age": 31,
                            "id": 3
                        },
                        {
                            "type": "group",
                            "id": "4",
                            "name": "Cars",
                            "items": [
                                {
                                    "username": "Mary",
                                    "password": "sdfffdsa",
                                    "age": 31,
                                    "id": 4
                                }
                            ],
                        }
                    ]
                }
            ]
        }

    ]
  }


 ];

edit : я попытался создать функцию с рекурсией, которая находит соответствующие связанные группы.это работает, но я не знаю, как объединить пользователей.

 function checkChildren(group) {
  const allChildren = insideGroups[group.id];
  if (!allChildren) return group;
  const childGroups = allChildren.map((findChildrenID) => {
      const indexGroups = groups.findIndex((subGroup) => subGroup.id === 
    findChildrenID);
    return checkChildren(groups[indexGroups]);
    });
   return Object.assign({}, group, {groups: childGroups});
   }

1 Ответ

0 голосов
/ 26 июня 2018

Вы можете взять хеш-таблицу для различных типов данных для более быстрого доступа без итерации массивов объектов.

В случае пользователей вам все равно нужен новый объект с новыми свойствами и переименованными ключами.

Затем вам нужно новое свойство для корневых объектов и добавить его к свойству groups.groups, чтобы иметь одинаковый тип доступа для всех уровней.

После окончания итерации сначала groups.usersа затем groups.groups, чтобы получить весь объект и для групп, также взять детей.

В приведенных данных я прокомментировал неиспользуемые / дублирующиеся данные.

function getNodes(node) {
    return [
        ...(hash.groups.users[node] || []).map(id => hash.user[id]),
        ...(hash.groups.groups[node] || []).map(id => Object.assign(hash.group[id], { children: getNodes(id) }))
    ];
}

var db = {
        group: [
            { groupName: "ROOT", id: 1 },
            { groupName: "Family", id: 9 },
            { groupName: "BestFriends!", id: 10 },
            { groupName: "Cars", id: 4 },
            { groupName: "funHouse", id: 3 }
        ],
        user: [
            { username: "StrongGoose", password: "sdff12fdsa", age: 31, id: 2 },
            { username: "John", password: "sdjd34fffdsa", age: 31, id: 3 },
            { username: "Mary", password: "sdfffdsa", age: 31, id: 4 }
        ],
        GroupsToGroups: [
            { 1: [9, 10] }, // ok
            { 10: [3] },    // second
            { 3: [4] }
        ],
        GroupsToUsers: [
            //{ 11: [2] }, // never used
            { 3: [3] },
            { 4: [4] },
            { 10: [2] },   // first
            //{ 3: [3] }   // dupe
        ]
    },
    hash = {
        group: Object.assign(...db.group.map(({ id, groupName: name, type = 'group' }) => ({ [id]: { type, id, name } }))),
        user: Object.assign(...db.user.map(o => ({ [o.id]: o }))),
        groups: {
            groups: Object.assign(...db.GroupsToGroups, { root: db.group.filter(({ groupName }) => groupName === 'ROOT').map(({ id }) => id) }),
            users: Object.assign(...db.GroupsToUsers)
        }
    },
    result = getNodes('root');

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...