我正在努力將兩個物件陣列(從區塊鏈資料中獲取)合并到一個基于物件值的新陣列中。
目標是獲得與用戶的最新互動。
這個問題面臨的資料結構的簡化但緊密的表示:
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,
},
},
];
所需結果應包含“發送給”或“由相應用戶接收”的最新 messageId。像這樣的東西:
const latestInteraction = [
{
user: "userId1",
messageId: "messageId2",
timestamp: 102,
},
{
user: "userId2",
messageId: "messageId3",
timestamp: 103,
},
{
user: "userId3",
messageId: "messageId5",
timestamp: 105,
},
]
作為一種解決方案,我考慮回圈遍歷陣列,每次迭代也回圈遍歷另一個陣列以比較senderId
和receiverId
值。如果“senderId
是==回圈receiverId
的s之一”,則可以將其發送到interaction
陣列中,然后進行時間排序和過濾。不幸的是,我不知道如何讓它作業。另外,我認為我的想法可能在這里受到限制,并且可能有比我的解決方案概念更有效的方法來做到這一點。
uj5u.com熱心網友回復:
我采取的方法是將您接收和發送的訊息轉換為一個“互動”陣列,其中僅包含您關心的資訊。對于收到的訊息,您希望查看senderId
,而對于發送的訊息,您希望查看receiverId
(想法是您希望其他用戶進行每次互動,而不是當前用戶)。這可能看起來像這樣:
interface Interaction {
user: string
messageId: string
timestamp: number
}
function latestInteractions(
receivedMsgs: MsgSlice[],
sentMsgs: MsgSlice[]
): Interaction[] {
const allInteractions: Interaction[] = [];
for (const m of receivedMsgs) {
const sender = m.messageDataSlice.senderId;
if (sender === undefined) continue;
allInteractions.push({
user: sender,
messageId: m.messageId,
timestamp: m.messageDataSlice.timestamp
});
}
for (const m of sentMsgs) {
allInteractions.push({
user: m.messageDataSlice.receiverId,
messageId: m.messageId,
timestamp: m.messageDataSlice.timestamp
});
}
請注意,如果以某種方式收到的訊息沒有 asenderId
那么我們就跳過它。也許我們應該拋出一個錯誤?這取決于你。現在我們有一個包含所有互動的陣列。我們只想為user
陣列中的每一個收集一個這樣的互動,如果我們有多個互動,我們應該只保留一個最大的互動timestamp
。這可能看起來像這樣:
const interactionMap: { [k: string]: Interaction } = {};
for (const i of allInteractions) {
if (!(i.user in interactionMap) || interactionMap[i.user].timestamp < i.timestamp) {
interactionMap[i.user] = i;
}
}
現在interactionMap
是一個普通物件,其鍵是user
字串,其值是Interaction
每個用戶的最新值。這包含了我們想要的所有資訊,但您需要的是陣列而不是物件。所以我們可以只使用該Object.values()
方法來獲取值的陣列:
return Object.values(interactionMap);
}
那是按某種順序排列的陣列;如果你關心你可以sort
根據你的需要。
讓我們確保它適用于您的示例:
const latestInteraction = latestInteractions(latestReceivedMsgs, latestSentMsgs);
console.log(latestInteraction);
/* [{
"user": "userId1",
"messageId": "messageId2",
"timestamp": 102
}, {
"user": "userId2",
"messageId": "messageId3",
"timestamp": 103
}, {
"user": "userId3",
"messageId": "messageId5",
"timestamp": 105
}] */
看起來不錯!
Playground 代碼鏈接
uj5u.com熱心網友回復:
您可以使用哈希分組方法,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 }
uj5u.com熱心網友回復:
您可以簡單地將兩個陣列扁平化為一個,然后按時間戳對它們進行排序。如:
let msgs: MsgSlice[] = [];
msgs.push(...latestReceivedMsgs);
msgs.push(...latestSentMsgs);
msgs.sort((a, b) => {
return a.timestamp - b.timestamp ;
});
uj5u.com熱心網友回復:
也許您可以將它們加入一個陣列,然后按它們的時間戳對它們進行排序?
const sortedMsgs = [...latestReceivedMsgs, ...latestSentMsgs] sortedMsgs.sort((a,b)=>a.messageDataSlice.timestamp-b.messageDataSlice.timestamp)
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/506179.html
標籤:javascript 数组 打字稿 目的 数组合并
下一篇:如何獲取先前兄弟的輸入的值?