我正在努力根據特定條件從一組物件中檢索一個子集。我有以下格式的物件陣列:
const messages = [
{
summary: '[x1fg66pwq-qft] Second reminder to submit supporting documents',
date: '1624652200',
type: 1
},
{
summary: '[x1fg66pwq-fgh] Final reminder to submit supporting documents',
date: '1629058600',
type: 4
},
{
summary: '[zy9l89ptb-yuw] Please submit your proof of address',
date: '1631708200',
type: 2
},
{
summary: '[ggk9nygh8-pmn] Your application has been successful.',
date: '1634300200',
type: 1
},
]
還有另一個陣列,它根據摘要方括號中的訊息 ID 提供要檢索的訊息:
const messageIds = ['x1fg66pwq', 'zy9l89ptb'];
結果應該是根據messageIds陣列中的內容檢索最新訊息。日期欄位在紀元中。
const result = [
{
summary: '[x1fg66pwq] Final reminder to submit supporting documents',
date: '1629058600',
type: 4
},
{
summary: '[zy9l89ptb] Please submit your proof of address',
date: '1631708200',
type: 2
},
]
為了實作上述目標,我嘗試組合一個過濾器并找到對我不起作用的過濾器:
const result = messages.filter((message) =>
messageIds.find(id => message.summary.includes(testEvent))
);
我希望上面的內容回傳具有指定摘要的陣列中的第一個結果。但是,這總是為我回傳完整的陣列而無需過濾。有人可以幫我實作這一目標嗎?
uj5u.com熱心網友回復:
在查找latest 時,您可以首先創建一個映射或普通物件,以目標訊息 ID 為鍵,然后將其date屬性具有最大值的訊息分配給每個訊息:
const messages = [{summary: '[x1fg66pwq-qft] Second reminder to submit supporting documents',date: '1624652200',type: 1},{ summary: '[x1fg66pwq-fgh] Final reminder to submit supporting documents',date: '1629058600', type: 4},{ summary: '[zy9l89ptb-yuw] Please submit your proof of address',date: '1631708200',type: 2},{ summary: '[ggk9nygh8-pmn] Your application has been successful.', date: '1634300200',type: 1},];
const messageIds = ['x1fg66pwq', 'zy9l89ptb'];
// Create object keyed by the message ids:
let obj = Object.fromEntries(messageIds.map(id => [id, null]));
// Link the message to each id with minimal date
for (let msg of messages) {
let id = msg.summary.match(/^\[(.*?)-/)?.[1];
if (obj[id] === null || msg.date > obj[id]?.date) obj[id] = msg;
}
let result = Object.values(obj);
console.log(result);
uj5u.com熱心網友回復:
這部分很容易。這只是將它們串在一起的問題:
const matches = (messages, ids) => ids .flatMap (
id => messages .filter (({summary}) => summary .startsWith ('[' id))
.sort (({date: a}, {date: b}) => b - a)
.slice (0, 1)
)
const messages = [{summary: '[x1fg66pwq-qft] Second reminder to submit supporting documents', date: '1624652200', type: 1}, {summary: '[x1fg66pwq-fgh] Final reminder to submit supporting documents', date: '1629058600', type: 4}, {summary: '[zy9l89ptb-yuw] Please submit your proof of address', date: '1631708200', type: 2}, {summary: '[ggk9nygh8-pmn] Your application has been successful.', date: '1634300200', type: 1}]
const messageIds = ['x1fg66pwq', 'zy9l89ptb']
console .log (matches (messages, messageIds))
此版本將簡單地忽略不匹配的 ID。這可能是也可能不是您想要的。如果您必須為每個 id 搜索大量資料,它也會做一些愚蠢的事情:它通過對它們進行排序并選擇第一個來找到最大值。對于小資料,這很好。對于較大的資料(數十萬或數百萬可能首先成為問題的地方),這是O (n log (n)),這比以下技術慢,這是O (n):
const maxBy = (fn) => (xs) => xs .reduce (
({curr, max}, x) => fn(x) > max ? {curr: x, max: fn (x)} : {curr, max},
{curr: null, max: -Infinity}
) .curr
const matches = (messages, ids) => ids .flatMap (
id => maxBy (({date}) => Number(date))
(messages .filter (({summary}) => summary .startsWith ('[' id)))
)
const messages = [{summary: '[x1fg66pwq-qft] Second reminder to submit supporting documents', date: '1624652200', type: 1}, {summary: '[x1fg66pwq-fgh] Final reminder to submit supporting documents', date: '1629058600', type: 4}, {summary: '[zy9l89ptb-yuw] Please submit your proof of address', date: '1631708200', type: 2}, {summary: '[ggk9nygh8-pmn] Your application has been successful.', date: '1634300200', type: 1}]
const messageIds = ['x1fg66pwq', 'zy9l89ptb']
console .log (matches (messages, messageIds))
這使用一個maxBy函式遍歷串列以根據提供的函式找到最大值,回傳null一個空陣列。
如果null未找到 id,此版本將包含在輸出中。這可能是首選行為,但如果不是,您可以包裝它以過濾非空值的輸出。
顯然,在這些解決方案中的任何一個中,您都可以替換summary .startsWith ('[' id)為summary .includes (id),這更靈活,但可能不太準確。
uj5u.com熱心網友回復:
sort如果我正確理解你的問題,我認為你只需要在最后加上一個
.sort((b,a) => a.date - b.date)
const messages = [{
summary: '[x1fg66pwq-qft] Second reminder to submit supporting documents',
date: '1624652200',
type: 1
},
{
summary: '[x1fg66pwq-fgh] Final reminder to submit supporting documents',
date: '1629058600',
type: 4
},
{
summary: '[zy9l89ptb-yuw] Please submit your proof of address',
date: '1631708200',
type: 2
},
{
summary: '[ggk9nygh8-pmn] Your application has been successful.',
date: '1634300200',
type: 1
},
]
const messageIds = ['x1fg66pwq', 'zy9l89ptb'];
const result = messages.filter((message) =>
messageIds.some(id => message.summary.includes(id))
).sort((b, a) => a.date - b.date);
console.log(result)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/388168.html
標籤:javascript 数组 算法 ecmascript-6 过滤
