我正在努力将两个对象数组(从区块链数据中提取)合并为一个基于对象值的新array.

其目标是获得与用户的最新交互.

A simplified but close representation of the data structure this problem is faced in:

interface MsgSlice {
    messageId: string;
    messageDataSlice: {
        senderId?: string;
        receiverId: string;
        timestamp: number;
    };
};

const latestReceivedMsgs: MsgSlice[] = [
    {
        messageId: "messageId1",
        messageDataSlice: {
            senderId: "userId1",
            receiverId: "ownerId", // <- always same in that array
            timestamp: 101,
        },
    },
    {
        messageId: "messageId3",
        messageDataSlice: {
            senderId: "userId2",
            receiverId: "ownerId",
            timestamp: 103,
        },
    },
    {
        messageId: "messageId5",
        messageDataSlice: {
            senderId: "userId3",
            receiverId: "ownerId",
            timestamp: 105,
        },
    },
];

const latestSentMsgs: MsgSlice[] = [
    {
        messageId: "messageId2",
        messageDataSlice: {
            // senderId: "ownerId",
            receiverId: "userId1",
            timestamp: 102,
        },
    },
    {
        messageId: "messageId4",
        messageDataSlice: {
            receiverId: "userId3",
            timestamp: 104,
        },
    },
];

所需结果应包含‘发送给’相应用户或‘由’相应用户‘接收’的最新消息ID.大概是这样的:


const latestInteraction = [
    {
        user: "userId1",
        messageId: "messageId2",
        timestamp: 102,
    },
    {
        user: "userId2",
        messageId: "messageId3",
        timestamp: 103,
    },
    {
        user: "userId3",
        messageId: "messageId5",
        timestamp: 105,
    },
]   

作为解决方案,我想到了循环遍历数组,每次迭代也循环遍历另一个数组,以比较senderIdreceiverId的值.如果"senderId是==循环的receiverId中的一个",它可以被发送到interaction数组中,然后对时间进行排序和过滤.不幸的是,我想不出如何让它工作.此外,我认为我的 idea 可能局限在这里,可能有比我的解决方案概念更有效的方法来做到这一点.

推荐答案

您可以使用散列分组方法Vanila JS解决方案

现场演示:

const latestReceivedMsgs = [{messageId: "messageId1",messageDataSlice: {senderId: "userId1",receiverId: "ownerId", timestamp: 101,},},{messageId: "messageId3",messageDataSlice: {senderId: "userId2",receiverId: "ownerId",timestamp: 103,},},{messageId: "messageId5",messageDataSlice: {senderId: "userId3",receiverId: "ownerId",timestamp: 105,},},];
const latestSentMsgs = [{messageId: "messageId2",messageDataSlice: {receiverId: "userId1",timestamp: 102,},},{messageId: "messageId4",messageDataSlice: {receiverId: "userId3",timestamp: 104,},},];

const grouped = [...latestReceivedMsgs, ...latestSentMsgs]
  .reduce((acc, { messageId, messageDataSlice }) => {
    const { timestamp, senderId, receiverId } = messageDataSlice;
    const user = senderId ?? receiverId;
    const msgItem = { user, messageId, timestamp };
    if ((acc[user]?.timestamp ?? 0) < timestamp) acc[user] = msgItem;
    
    return acc;
  }, {});

const result = Object.values(grouped);

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

UPDATE

或打字变体:

interface MsgSlice {
  messageId: string;
  messageDataSlice: {
    senderId?: string;
    receiverId?: string;
    timestamp: number;
  };
};

interface Interaction {
  user: string
  messageId: string
  timestamp: number
};

const latestReceivedMsgs: MsgSlice[] = [{messageId: "messageId1",messageDataSlice: {senderId: "userId1",receiverId: "ownerId", // <- always same in that array},},{messageId: "messageId3",messageDataSlice: {senderId: "userId2",receiverId: "ownerId",timestamp: 103,},},{messageId: "messageId5",messageDataSlice: {senderId: "userId3",receiverId: "ownerId",timestamp: 105,},},];
const latestSentMsgs: MsgSlice[] = [{messageId: "messageId2",messageDataSlice: {receiverId: "userId1",timestamp: 102,},},{messageId: "messageId4",messageDataSlice: {receiverId: "userId3",timestamp: 104,},},];

const grouped = ([...latestReceivedMsgs, ...latestSentMsgs] as MsgSlice[])
  .reduce((acc, { messageId, messageDataSlice }) => {
    const { timestamp, senderId, receiverId } = messageDataSlice;
    const user = senderId ?? receiverId ?? "unindefined";
    const msgItem = { user, messageId, timestamp };
    if ((acc[user]?.timestamp ?? 0) < timestamp) acc[user] = msgItem
    
    return acc;
  }, {} as { [key: Interaction['user']]: Interaction });

const result: Interaction[] = Object.values(grouped);

console.log(result);

Javascript相关问答推荐

使用reaction创建可排序的表不起作用

验证嵌套 colored颜色 代码的结果

在Chart.js 4.4.2中移动到不同大小的容器时,图表不会调整大小

如何使用Paged.js仅渲染特定页面

我应该在redux reducer中调用其他reducer函数吗?

zoom svg以适应圆

通过在页面上滚动来移动滚动条

将2D数组转换为图形

如何为我的astro页面中的相同组件自动创建不同的内容?

如何添加绘图条形图图例单击角形事件

如何从URL获取令牌?

如何在Vue 3中创建自定义 Select 组件,并将选项作为HTML而不是props 传递?

XSLT处理器未运行

S文本内容和值不必要的不同

在我的index.html页面上找不到我的Java脚本条形图

为什么客户端没有收到来自服务器的响应消息?

如何在Bootstrap中减少网格系统中单个div的宽度

元素字符串长度html

为什么NULL不能在构造函数的.Prototype中工作

select 2-删除js插入的项目将其保留为选项