首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在新计算的查询数据上为数组项创建自定义筛选条件?

如何在新计算的查询数据上为数组项创建自定义筛选条件?
EN

Stack Overflow用户
提问于 2021-08-23 21:04:28
回答 1查看 261关注 0票数 0

我有一个过滤器对象,它由查询参数返回。

url = /all?channels=calls,text&calls=voicemail,missed

代码语言:javascript
复制
const query = {
  channels: 'calls,texts',
  calls: 'voicemail,missed',
};

然后,我有一个来自套接字的对象数组。

代码语言:javascript
复制
const arr = [
  {
    id: 1,
    channel: 'SMS',
    sent: '2021-08-22T03:21:18.41650+0000',
    sender: {
      contactType: 'business',
    },
    recipients: [
      {
        contactType: 'corporate',
      },
    ],
    direction: 'INBOUND',
  },
  {
    id: 2,
    channel: 'VOICE',
    sent: '2021-08-20T23:15:56.00000+0000',
    sender: {
      contactType: 'business',
    },
    recipients: [
      {
        contactType: 'corporate',
      },
    ],
    callDetails: {
      answered: false,
      voicemail: true,
    },
    direction: 'INBOUND',
  },
  {
    id: 3,
    channel: 'VOICE',
    sent: '2021-08-20T23:15:56.00000+0000',
    sender: {
      contactType: 'business',
    },
    recipients: [
      {
        contactType: 'corporate',
      },
    ],
    callDetails: {
      answered: true,
      voicemail: false,
    },
    direction: 'INBOUND',
  },
  {
    id: 4,
    channel: 'VOICE',
    sent: '2021-08-20T23:15:56.00000+0000',
    sender: {
      contactType: 'business',
    },
    recipients: [
      {
        contactType: 'corporate',
      },
    ],
    callDetails: {
      answered: false,
      voicemail: false,
    },
    direction: 'INBOUND',
  },
];

我想过滤掉与过滤器匹配的对象,但是query obj不够友好,不能只映射arr

使用上面共享的查询obj,我应该从id:1id:2id:4返回arr对象,因为这些对象符合sms, voicemail, & missed的条件。

我假设我需要一个修改过的查询obj,它必须对每个属性都有不同的可用条件,即calls: voicemail === callDetails.voicemail === truecalls: received === callDetails.answered === true

我已经看到了很多关于如何过滤具有多个匹配条件的对象数组的例子,但是由于属性的req有多个条件,所以我遇到了麻烦。

谢谢你的帮助

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-08-24 00:18:13

其主要思想是提供一种rosetta ,它用任何列表项的特定数据结构来桥接/映射query特定的语法。因此,最终会编写一个映射,它考虑到了query的结构,但确保了每个必要的查询端点都有一个特定于项的筛选条件/函数。

查询函数应该简单地通过应用逻辑或条件列表来filter项列表,从而使用some返回布尔筛选器值。

这就留下了一个实现助手方法来收集.通过和以及和 .上述函数端点介绍了基于requirements对象的query配置/映射。因此,这个助手可能被命名为resolveQuery

代码语言:javascript
复制
const sampleList = [{
  id: 1,
  channel: 'SMS',

  direction: 'INBOUND',
}, {
  id: 2,
  channel: 'VOICE',

  callDetails: {
    answered: false,
    voicemail: true,
  },
  direction: 'INBOUND',
}, {
  id: 3,
  channel: 'VOICE',

  callDetails: {
    answered: true,
    voicemail: false,
  },
  direction: 'INBOUND',
}, {
  id: 4,
  channel: 'VOICE',

  callDetails: {
    answered: false,
    voicemail: false,
  },
  direction: 'INBOUND',
}];

// prepare a `requirements` map which ...
// - on one hand maps `query`-syntax to a list items's structure
// - and on the other hand does so by providing an item specific
//   filter condition/function for each necessary query endpoint.
const requirements = {
  channels: {
    texts: item => item.channel === 'SMS',
  },
  calls: {
    voicemail: item => item.channel === 'VOICE' && !!item.callDetails.voicemail,
    missed: item => item.channel === 'VOICE' && !item.callDetails.answered,
  },
}
// const query = {
//   channels: 'calls,texts',
//   calls: 'voicemail,missed',
// };

function resolveQuery(requirements, query) {
  const reject = item => false;

  // create/collect a list of filter condition/functions
  // which later will be applied as logical OR via `some`.
  return Object

    .entries(query)
    .flatMap(([ groupKey, groupValue ]) =>
      // e.g groupKey => 'channels',
      // groupValue => 'calls,texts'
      groupValue
        .split(',')
        .map(requirementKey =>
          // e.g requirementKey => 'calls'
          // or requirementKey => 'texts'
          requirements?.[groupKey]?.[requirementKey?.trim()] ?? reject
        )
    );
}

function queryFromItemList(itemList, requirements, query) {
  const conditionList = resolveQuery(requirements, query);

  console.log(
    'conditionList ... [\n ',
    conditionList.join(',\n  '),
    '\n]'
  );

  return itemList.filter(item =>
    conditionList.some(condition => condition(item))
  );
}

console.log(
  queryFromItemList(sampleList, requirements, {
    channels: 'calls,texts',
    calls: 'voicemail,missed',
  })
);
代码语言:javascript
复制
.as-console-wrapper { min-height: 100%!important; top: 0; }

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

https://stackoverflow.com/questions/68898998

复制
相关文章

相似问题

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