合并在一系列物体中的重复和突变一些属性JavaScript
我有一个复杂的场景,在其中我需要在一系列对象中找到重复,并将它们合并以突变某些属性值。
数据来自一个对酒店保留的Excel文件,每个预订都有一个revervationNumber
,当数组包含2个或更多的保留量,具有相同的proceservationnumber
IT意味着它是相同的预订,但是有多个房间,所以我需要合并它们,但是第一个项目应保留为roomnumber
(这是主房间),其余重复应汇总到extair_rooms
(这是一个简单的数组,包含剩余的房间号,不包括主房间);另外,它需要汇总到具有以下结构的extramages
属性:
extraRoomsAges: [
{
room: 34, // We get this from the roomNumber property
// We get this from the mainRoomDistribution property
adults: 0,
infants: 0,
},
],
因此,要更广泛地了解问题,这是我需要处理的数据的一个示例:
const data = [
{
reservationNumber: 'RX-0032466',
fullName: 'John Doe',
firstName: 'John',
lastName: 'Doe',
documentType: 'dni',
hotel: 'hpp',
documentID: null,
extra_rooms: [],
extraRoomsAges: [],
mainRoomDistribution: {
adults: 2,
infants: 0,
},
totalCharges: 1754.28,
agencyCode: 5,
roomNumber: '63',
},
{
reservationNumber: 'RX-0032466',
fullName: 'John Doe',
firstName: 'John',
lastName: 'Doe',
documentType: 'dni',
hotel: 'hpp',
documentID: null,
extra_rooms: [],
extraRoomsAges: [],
mainRoomDistribution: {
adults: 3,
infants: 1,
},
totalCharges: 1954.49,
agencyCode: 5,
roomNumber: '64',
},
{
reservationNumber: 'RX-0032466',
fullName: 'John Doe',
firstName: 'John',
lastName: 'Doe',
documentType: 'dni',
hotel: 'hpp',
documentID: null,
extra_rooms: [],
extraRoomsAges: [],
mainRoomDistribution: {
adults: 1,
infants: 0,
},
totalCharges: 850.30,
agencyCode: 5,
roomNumber: '65',
},
{
reservationNumber: 'RX-0032494',
fullName: 'Jane Foster',
firstName: 'Jane',
lastName: 'Foster',
documentType: 'dni',
hotel: 'hpp',
documentID: '123456789',
extra_rooms: [],
extraRoomsAges: [],
mainRoomDistribution: {
adults: 4,
infants: 0,
},
totalCharges: 1540,
agencyCode: 13,
roomNumber: '40',
},
]
结果应该像这样
[
{
reservationNumber: 'RX-0032466',
fullName: 'John Doe',
firstName: 'John',
lastName: 'Doe',
documentType: 'dni',
hotel: 'hpp',
documentID: null,
extra_rooms: [64, 65], // aggregates the remaining occurrences from the roomNumber property
extraRoomsAges: [
{
room: 64,
adults: 3,
infants: 1
},
{
room: 65,
adults: 1,
infants: 0,
}
],
mainRoomDistribution: {
adults: 2,
infants: 0,
},
totalCharges: 4559.07, //the sum of all the occurrences
agencyCode: 5,
roomNumber: '63', //remains as the main room from the first occurrence
},
{
reservationNumber: 'RX-0032494',
fullName: 'Jane Foster',
firstName: 'Jane',
lastName: 'Foster',
documentType: 'dni',
hotel: 'hpp',
documentID: null,
extra_rooms: [],
extraRoomsAges: [],
mainRoomDistribution: {
adults: 4,
infants: 0,
},
totalCharges: 1540,
agencyCode: 13,
roomNumber: '40',
},
]
:我已经尝试使用此功能合并重复:
export function mergeObjectsInUnique<T>(array: T[], property: any): T[] {
const newArray = new Map();
array.forEach((item: T) => {
const propertyValue = item[property];
newArray.has(propertyValue)
? newArray.set(propertyValue, { ...item, ...newArray.get(propertyValue) })
: newArray.set(propertyValue, item);
});
return Array.from(newArray.values());
}
console.log(mergeObjectsInUnique(data, 'reservationNumber'))
您可以看到这将正确合并了重复项,但是我只是找不到一种方法可以根据需要正确变异数据。
带有当前代码的摘要
const data = [{
reservationNumber: 'RX-0032466',
fullName: 'John Doe',
firstName: 'John',
lastName: 'Doe',
documentType: 'dni',
hotel: 'hpp',
documentID: null,
extra_rooms: [],
extraRoomsAges: [],
mainRoomDistribution: {
adults: 2,
infants: 0,
},
totalCharges: 1754.28,
agencyCode: 5,
roomNumber: '63',
},
{
reservationNumber: 'RX-0032466',
fullName: 'John Doe',
firstName: 'John',
lastName: 'Doe',
documentType: 'dni',
hotel: 'hpp',
documentID: null,
extra_rooms: [],
extraRoomsAges: [],
mainRoomDistribution: {
adults: 3,
infants: 1,
},
totalCharges: 1954.49,
agencyCode: 5,
roomNumber: '64',
},
{
reservationNumber: 'RX-0032466',
fullName: 'John Doe',
firstName: 'John',
lastName: 'Doe',
documentType: 'dni',
hotel: 'hpp',
documentID: null,
extra_rooms: [],
extraRoomsAges: [],
mainRoomDistribution: {
adults: 1,
infants: 0,
},
totalCharges: 850.30,
agencyCode: 5,
roomNumber: '65',
},
{
reservationNumber: 'RX-0032494',
fullName: 'Jane Foster',
firstName: 'Jane',
lastName: 'Foster',
documentType: 'dni',
hotel: 'hpp',
documentID: '123456789',
extra_rooms: [],
extraRoomsAges: [],
mainRoomDistribution: {
adults: 4,
infants: 0,
},
totalCharges: 1540,
agencyCode: 13,
roomNumber: '40',
},
]
function mergeObjectsInUnique(array, property) {
const newArray = new Map();
array.forEach((item) => {
const propertyValue = item[property];
newArray.has(propertyValue) ?
newArray.set(propertyValue, { ...item,
...newArray.get(propertyValue)
}) :
newArray.set(propertyValue, item);
});
return Array.from(newArray.values());
}
console.log(mergeObjectsInUnique(data, 'reservationNumber'))
玩的JSFIDDLE:
这是一个可以 如果可能的话,请解释答案。
提前致谢。
I have this complex scenario in which I need to find duplicates in an array of objects, and merge them mutating some property values.
The data comes from an excel file which has reservations for an hotel, each reservation has a reservationNumber
which is unique, when the array contains 2 or more reservations with the same reservationNumber
it means that it's the same reservation but with multiple rooms, so I need them to be merged, but the first item should remain as the roomNumber
(which is the main room) and the rest of the duplicates should aggregate to extra_rooms
(which is a simple array containing the remaining room numbers, excluding the main room); Also it needs to aggregate to extraRoomsAges
property with the following structure:
extraRoomsAges: [
{
room: 34, // We get this from the roomNumber property
// We get this from the mainRoomDistribution property
adults: 0,
infants: 0,
},
],
So to get a wider view of the problem this is an example of the data I need to process:
const data = [
{
reservationNumber: 'RX-0032466',
fullName: 'John Doe',
firstName: 'John',
lastName: 'Doe',
documentType: 'dni',
hotel: 'hpp',
documentID: null,
extra_rooms: [],
extraRoomsAges: [],
mainRoomDistribution: {
adults: 2,
infants: 0,
},
totalCharges: 1754.28,
agencyCode: 5,
roomNumber: '63',
},
{
reservationNumber: 'RX-0032466',
fullName: 'John Doe',
firstName: 'John',
lastName: 'Doe',
documentType: 'dni',
hotel: 'hpp',
documentID: null,
extra_rooms: [],
extraRoomsAges: [],
mainRoomDistribution: {
adults: 3,
infants: 1,
},
totalCharges: 1954.49,
agencyCode: 5,
roomNumber: '64',
},
{
reservationNumber: 'RX-0032466',
fullName: 'John Doe',
firstName: 'John',
lastName: 'Doe',
documentType: 'dni',
hotel: 'hpp',
documentID: null,
extra_rooms: [],
extraRoomsAges: [],
mainRoomDistribution: {
adults: 1,
infants: 0,
},
totalCharges: 850.30,
agencyCode: 5,
roomNumber: '65',
},
{
reservationNumber: 'RX-0032494',
fullName: 'Jane Foster',
firstName: 'Jane',
lastName: 'Foster',
documentType: 'dni',
hotel: 'hpp',
documentID: '123456789',
extra_rooms: [],
extraRoomsAges: [],
mainRoomDistribution: {
adults: 4,
infants: 0,
},
totalCharges: 1540,
agencyCode: 13,
roomNumber: '40',
},
]
The result should look like this:
[
{
reservationNumber: 'RX-0032466',
fullName: 'John Doe',
firstName: 'John',
lastName: 'Doe',
documentType: 'dni',
hotel: 'hpp',
documentID: null,
extra_rooms: [64, 65], // aggregates the remaining occurrences from the roomNumber property
extraRoomsAges: [
{
room: 64,
adults: 3,
infants: 1
},
{
room: 65,
adults: 1,
infants: 0,
}
],
mainRoomDistribution: {
adults: 2,
infants: 0,
},
totalCharges: 4559.07, //the sum of all the occurrences
agencyCode: 5,
roomNumber: '63', //remains as the main room from the first occurrence
},
{
reservationNumber: 'RX-0032494',
fullName: 'Jane Foster',
firstName: 'Jane',
lastName: 'Foster',
documentType: 'dni',
hotel: 'hpp',
documentID: null,
extra_rooms: [],
extraRoomsAges: [],
mainRoomDistribution: {
adults: 4,
infants: 0,
},
totalCharges: 1540,
agencyCode: 13,
roomNumber: '40',
},
]
So far I've tried with this function to merge duplicates:
export function mergeObjectsInUnique<T>(array: T[], property: any): T[] {
const newArray = new Map();
array.forEach((item: T) => {
const propertyValue = item[property];
newArray.has(propertyValue)
? newArray.set(propertyValue, { ...item, ...newArray.get(propertyValue) })
: newArray.set(propertyValue, item);
});
return Array.from(newArray.values());
}
console.log(mergeObjectsInUnique(data, 'reservationNumber'))
As you can see this merges the duplicates correctly, but I just can't find a way to mutate the data properly as I need it.
Snippet with current code
const data = [{
reservationNumber: 'RX-0032466',
fullName: 'John Doe',
firstName: 'John',
lastName: 'Doe',
documentType: 'dni',
hotel: 'hpp',
documentID: null,
extra_rooms: [],
extraRoomsAges: [],
mainRoomDistribution: {
adults: 2,
infants: 0,
},
totalCharges: 1754.28,
agencyCode: 5,
roomNumber: '63',
},
{
reservationNumber: 'RX-0032466',
fullName: 'John Doe',
firstName: 'John',
lastName: 'Doe',
documentType: 'dni',
hotel: 'hpp',
documentID: null,
extra_rooms: [],
extraRoomsAges: [],
mainRoomDistribution: {
adults: 3,
infants: 1,
},
totalCharges: 1954.49,
agencyCode: 5,
roomNumber: '64',
},
{
reservationNumber: 'RX-0032466',
fullName: 'John Doe',
firstName: 'John',
lastName: 'Doe',
documentType: 'dni',
hotel: 'hpp',
documentID: null,
extra_rooms: [],
extraRoomsAges: [],
mainRoomDistribution: {
adults: 1,
infants: 0,
},
totalCharges: 850.30,
agencyCode: 5,
roomNumber: '65',
},
{
reservationNumber: 'RX-0032494',
fullName: 'Jane Foster',
firstName: 'Jane',
lastName: 'Foster',
documentType: 'dni',
hotel: 'hpp',
documentID: '123456789',
extra_rooms: [],
extraRoomsAges: [],
mainRoomDistribution: {
adults: 4,
infants: 0,
},
totalCharges: 1540,
agencyCode: 13,
roomNumber: '40',
},
]
function mergeObjectsInUnique(array, property) {
const newArray = new Map();
array.forEach((item) => {
const propertyValue = item[property];
newArray.has(propertyValue) ?
newArray.set(propertyValue, { ...item,
...newArray.get(propertyValue)
}) :
newArray.set(propertyValue, item);
});
return Array.from(newArray.values());
}
console.log(mergeObjectsInUnique(data, 'reservationNumber'))
Here is a JSFiddle to play around:
https://jsfiddle.net/ou036zwv/
I'd appreciate an explanation with the answer if possible.
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我建议使用
array。降低()
在这里,使用reververationnumber
对预订进行分组。我们将为每个预订号码创建一个具有属性的对象,将每个预订分配给该属性。
如果预订已经存在预订编号,我们将通过将额外的房间号和额外的房间年龄附加到相关阵列来合并。我们还将将总费用添加到相关属性中。
合并到此对象后,我们将使用
object.values()
返回到数组。这种方法非常有效,所花费的时间将是O(n),因为ACC [el.ReservationNumber]查找将非常快。
I'd suggest using
Array.reduce()
here, grouping the reservations using thereservationNumber
.We'd create an object with properties for each reservation number, assigning each reservation to that property.
If a reservation already exists for the reservation number, we'll merge by appending the extra room numbers and extra room ages to the relevant arrays. We'd also add the totalCharges to the relevant property.
Once we've merged to this object, we'll use
Object.values()
to return to an array.This approach is very efficient, the time taken will be of order O(N), since the acc[el.reservationNumber] lookups will be very fast.