Я пытаюсь найти эффективный и кратчайший способ свести почти идентичные объекты в массиве в объекты, содержащие их собственные массивы с неидентичными данными. Звучит сложно, когда я пытаюсь это объяснить, позвольте мне показать вам, что я имею в виду:
У меня есть массив объектов, который выглядит следующим образом:
[{
id: '6b6574cf-d77a-4ed8-852f-cb60a0d377cd',
first_name: 'SomeName',
email: 'some@email.com',
rName: 'User', // 0,1
rAuthority: 'ROLE_USER', // 0,1
pId: 'e7da65a9-ea2d-4c77-82f6-e1addc78fb6e',
pMobile: '012 345 6789',
atId: '90db0c5d-3030-44aa-9dc0-40242af0d5c5', // 0,2
atPlatform: 'web',
},{
id: '6b6574cf-d77a-4ed8-852f-cb60a0d377cd',
first_name: 'SomeName',
email: 'some@email.com',
rName: 'User', // 0,1
rAuthority: 'ROLE_USER', // 0,1
pId: 'e7da65a9-ea2d-4c77-82f6-e1addc78fb6e',
pMobile: '012 345 6789',
atId: 'e7d53cab-a9b9-40ae-9271-11d79c2f269c', // 1,3
atPlatform: 'web',
},{
id: '6b6574cf-d77a-4ed8-852f-cb60a0d377cd',
first_name: 'SomeName',
email: 'some@email.com',
rName: 'Admin', // 2,3
rAuthority: 'ROLE_ADMIN', // 2,3
pId: 'e7da65a9-ea2d-4c77-82f6-e1addc78fb6e',
pMobile: '012 345 6789',
atId: '90db0c5d-3030-44aa-9dc0-40242af0d5c5', // 0,2
atPlatform: 'web',
},{
id: '6b6574cf-d77a-4ed8-852f-cb60a0d377cd',
first_name: 'SomeName',
email: 'some@email.com',
rName: 'Admin', // 2,3
rAuthority: 'ROLE_ADMIN', // 2,3
pId: 'e7da65a9-ea2d-4c77-82f6-e1addc78fb6e',
pMobile: '012 345 6789',
atId: 'e7d53cab-a9b9-40ae-9271-11d79c2f269c', // 1,3
atPlatform: 'web',
}]
// I point out which of the properties are not identical by adding
// quotes showing which indices of the array contains unique values of
// said property. If the there's not a quote to the right of the
// property it's identical across all indices.
Я хочу преобразовать этот массив в массив, в котором объекты с дублирующимися идентификаторами объединяются в один объект с массивами объектов, содержащих неидентичные данные. Это выглядит так:
[{
id: '6b6574cf-d77a-4ed8-852f-cb60a0d377cd',
first_name: 'SomeName',
email: 'some@email.com',
roles: [{
name: 'User',
authority: 'ROLE_USER'
},{
name: 'Admin',
authority: 'ROLE_ADMIN'
}],
profiles: [{
id: 'e7da65a9-ea2d-4c77-82f6-e1addc78fb6e',
mobile: '012 345 6789',
}],
tokens: [{
id: '90db0c5d-3030-44aa-9dc0-40242af0d5c5',
platform: 'web',
},{
id: 'e7d53cab-a9b9-40ae-9271-11d79c2f269c',
platform: 'web',
}]
}]
Как видите, все свойства предыдущего массива с префиксом r
теперь имеют свои объекты в массиве в свойстве roles
. p
префиксные свойства находятся в profiles
, а at
префиксные свойства находятся в tokens
. Объект считается «идентичным», если он имеет тот же id
, что и другой объект.
Вот код, который я написал, который, кажется, успешно преобразует первый массив во второй массив:
...then(data => {
let users = [];
// gets the correct formatting
data.forEach((d, i) => {
let found = false;
users.forEach((u, j) => {
if(d.id === u.id) {
u.roles.push({ name:d.rName, authority:d.rAuthority });
u.tokens.push({ id:d.atId, platform:d.atPlatform });
u.profiles.push({ id:d.pId, mobile:d.pMobile });
found = true;
}
});
if(!found) {
users.push({
id:d.id,
first_name:d.first_name,
email:d.email,
roles: [{ name:d.rName, authority:d.rAuthority }],
profiles: [{ id:d.pId, mobile:d.pMobile }],
tokens: [{ id:d.atId, platform:d.atPlatform }]
});
}
});
// remove duplicates from sub-arrays
users.forEach((user, i) => {
user.roles = _.uniqBy(user.roles, 'name');
user.profiles = _.uniqBy(user.profiles, 'id');
user.tokens = _.uniqBy(user.tokens, 'id');
});
});
У меня две проблемы с этим кодом. Во-первых, он очень длинный (на самом деле ради этого вопроса я удалил многие свойства из первого массива - в действительности каждый объект имеет более чем удвоенное количество свойств, которые вы видите здесь, что делает этот код намного длиннее), и во-вторых, у меня есть сильное подозрение, что это, вероятно, очень неэффективно.
Вопрос:
Может кто-нибудь помочь мне переписать код, который я использую для форматирования моего массива, во что-то более короткое и более эффективное. У меня действительно установлено lodash , поэтому я бы предпочел ответы, которые его использовали, но я с удовольствием также приму ответы vanilla.js.
Дополнительные примечания:
Этот вопрос является продолжением другого вопроса Я отправил. Если посмотреть на этот вопрос, то смутно покажу, откуда берутся данные, которые я пытаюсь преобразовать в этом вопросе. Короче говоря, это происходит из базы данных, это моя идея ленивой загрузки с использованием Knex.js. Идея состоит в том, что каждый пользователь может иметь несколько ролей, профилей и AuthTokens.