首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >根据另一个数组和条件筛选对象数组

根据另一个数组和条件筛选对象数组
EN

Stack Overflow用户
提问于 2021-12-15 20:39:44
回答 3查看 1.3K关注 0票数 2

我很难根据特定的条件从对象数组中检索子集。我有如下格式的对象数组:

代码语言:javascript
复制
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数组中的内容检索最新消息。日期字段是划时代的。

代码语言:javascript
复制
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
    },
]

为了实现上述目标,我尝试将一个过滤器组合在一起,发现它对我不起作用:

代码语言:javascript
复制
const result = messages.filter((message) =>
        messageIds.find(id => message.summary.includes(testEvent))
    );

我希望上面的结果返回数组中的第一个结果,该数组指定了摘要。但是,这总是为我返回完整的数组而不进行过滤。有人能帮我做到这一点吗?

EN

回答 3

Stack Overflow用户

发布于 2021-12-15 21:19:06

我认为如果我正确理解了你的问题,你只需要在最后插入一个sort

.sort((b,a) => +a.date - +b.date)

代码语言:javascript
复制
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)

票数 0
EN

Stack Overflow用户

发布于 2021-12-15 21:25:01

在查找最新消息时,您可以首先创建一个映射或普通对象,由目标消息ID键控,然后为每个消息分配具有其date属性最大价值的消息:

代码语言:javascript
复制
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);

票数 0
EN

Stack Overflow用户

发布于 2021-12-15 21:29:03

这件事很简单。这只是把它们串在一起的问题:

代码语言:javascript
复制
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))

这个版本只会忽略不匹配的ids。这可能是你想要的,也可能不是你想要的。如果您必须为每个id搜索大量数据,它还会做一些愚蠢的事情:它通过排序和选择第一个找到最大值。对于小数据来说,这很好。对于更大的数据(数亿或数以百万计的数据可能首先是一个问题),这是O (n log (n)),它比下面的技术O (n)

代码语言:javascript
复制
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

在没有找到id的情况下,此版本将在输出中包含null。这可能是首选行为,但如果不是,则可以将其包装以筛选非空值的输出。

显然,在这两种解决方案中,您都可以将summary .startsWith ('[' + id)替换为summary .includes (id),后者更灵活,但可能不太精确。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70370036

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档