正确过滤具有多个条件的对象数组和一个数组

Hoobs

我正在创建一个Todo App,作为学习PostgreSQL和使用JavaScript进行功能编程的练习。这个想法是,可以有多个容器,每个容器都有单独的过滤器设置,每个容器从Todos的主列表中读取数据,然后每个容器根据其过滤器设置显示其结果。这实际上是在React-Redux和Nodejs中完成的,但是我在下面的示例中做了更好的说明。

数据:

// Example todos
let a = {
  added: "2021-02-01T05:00:00.000Z",
  completed: null,
  description: "This is just a test.",
  name: "testing",
  tags: [],
  todo_id: 3,
}
let b = {
  added: "2021-02-01T05:00:00.000Z",
  completed: null,
  description: "This is just a test.",
  name: "testing",
  tags: ["one", "two"],
  todo_id: 4
}
let c = {
  added: "2021-02-01T05:00:00.000Z",
  completed: null,
  description: "This is just a test.",
  name: "tesin",
  tags: ["one"],
  todo_id: 5
}
let d = {
  added: "2021-02-01T05:00:00.000Z",
  completed: '2021-03-01T05:00:00.000Z',
  description: "This is just a test.",
  name: "testing",
  tags: ["two", "testing"],
  todo_id: 6
}

// Example filter_group 
// This is just to show what the initial state looks like in my React app
const filter_groups = {
  "main": {
    byTag: 'two',
    byName: '',
    byCompleted: true
  }
}

// Object.keys(filter_groups).map() passes the filter settings down as props
// Just stuck it in a variable for the example
const filter = filter_groups['main']

// Putting example Todos in array
const todo_list = [a,b,c,d]

当前的解决方案非常简单,丑陋且效率低下。它一次应用每个过滤器:

// ------- CURRENT SOLUTION ------- 

// if user is trying to filter byCompleted, then filter todo_list
// else do nothing todo_list and pass it to the next filter 
// (similar thing applies down the chain)
const byCompleted = filter.byCompleted === true ?
  todo_list.filter ( (t) => {
    return t.completed !== null
  })
  :
  todo_list


//IF user is trying to filter byTag...
const byTag = filter.byTag !== '' ?
  // THEN filter the byCompleted array above
  byCompleted.filter( (t) => {
    // IF there are tags on the Todo...
    let matches = t.tags ?
      // THEN filter for matches
      t.tags.filter( (tag) => {
        return tag === filter.byTag
      }) 
      : 
      // ELSE make this an empty array
      []

    // return any Todos with match
    return matches.length > 0
  })
  :
  byCompleted

// IF user is trying to filter byName...
const byName = filter.byName !== '' ?
  // THEN filter byTag Todos
  byTag.filter( (t) => {
    return t.name === P.filter.byName
  })
  :
  byTag

console.log(byName);

我真的很想知道是否有一种方法可以一次全部应用整个过滤器。在示例中,您将看到过滤器设置为byTag: 'two', byComplete: true使控制台仅输出一个结果的过滤器我过去尝试通过一次过滤器传递使事情生效的尝试将返回带有two标签的所有内容

我尝试查看了文档,发现过滤器功能还有更多功能,但是并没有点击,并且找不到适合我的用例的示例。

编辑:这是codeandbox上的全部内容:https ://codesandbox.io/s/recursing-almeida-cdz65 ? file =/ src/index.js

兰迪·卡斯本

您在问题中提到了函数编程。

下面的代码采用一种简单的方法来解决您的过滤问题。

一旦建立了单独的过滤器,将它们链接在一起就很简单。每个过滤器函数将返回一个数组,以供下一个函数操作。

注意:我必须推断一些细节。

let a = { added: "2021-02-01T05:00:00.000Z", completed: null, description: "This is just a test.", name: "testing", tags: [], todo_id: 3, } 
let b = { added: "2021-02-01T05:00:00.000Z", completed: null, description: "This is just a test.", name: "testing", tags: ["one", "two"], todo_id: 4 } 
let c = { added: "2021-02-01T05:00:00.000Z", completed: null, description: "This is just a test.", name: "tesin", tags: ["one"], todo_id: 5 } 
let d = { added: "2021-02-01T05:00:00.000Z", completed: '2021-03-01T05:00:00.000Z', description: "This is just a test.", name: "testing", tags: ["two", "testing"], todo_id: 6 } 

const filter_groups = { "main": { byTag: 'two', byName: '', byCompleted: true } }
const filter = filter_groups['main']

const todo_list = [a,b,c,d]

let byTag = td => td.tags.includes(filter.byTag);
let byName = td => filter.name ? td.tags.includes(filter.name) : true;
let byCompleted = td => filter.byCompleted ? td.completed !== null : false ;

let result = todo_list.filter(byTag).filter(byName).filter(byCompleted);

console.log(result);

编辑:OP要求在一个代码块中执行此操作。该解决方案如下:

let a = { added: "2021-02-01T05:00:00.000Z", completed: null, description: "This is just a test.", name: "testing", tags: [], todo_id: 3, };
let b = { added: "2021-02-01T05:00:00.000Z", completed: null, description: "This is just a test.", name: "testing", tags: ["one", "two"], todo_id: 4 }; 
let c = { added: "2021-02-01T05:00:00.000Z", completed: null, description: "This is just a test.", name: "tesin", tags: ["one"], todo_id: 5 }; 
let d = { added: "2021-02-01T05:00:00.000Z", completed: '2021-03-01T05:00:00.000Z', description: "This is just a test.", name: "testing", tags: ["two", "testing"], todo_id: 6 }; 

const todo_list = [a,b,c,d];

const filter_groups = { "main": { tags: 'two', name: '', completed: true } };

let result2 = todo_list.filter(td=>{
  return Object.entries(filter_groups['main'])
    .filter(([k,v])=>!!v!=false)
    .map(f=>!!td[f[0]])
    .every(f=>f==true);
});

console.log(result2);

OP还提到了他原始代码和“三步走”解决方案中有关性能的问题。

为了给您以通常的方式编写代码的信心,我使用jsben.ch.com进行了一系列测试。下图显示了OP的原始代码始终位于#2或#1处。“三步走”解决方案分享了这一结果。最重要的是,更多的步骤不一定等同于性能较差。如果可以让站点进行合作,请多次运行测试以了解性能差异。JSBEN.CH测试

用一粒盐获得这些结果-很好地显示了比较,但没有太多其他好处。

在此处输入图片说明

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么过滤具有多个条件的对象数组会返回一个空数组?

来自分类Dev

在javascript中基于具有多个数组的另一个对象的过滤来过滤数组

来自分类Dev

通过具有重复键的另一个数组过滤对象数组

来自分类Dev

用一个条件过滤多个数组

来自分类Dev

使用内部数组和另一个数组过滤对象数组

来自分类Dev

在一个数组中合并具有相同键值的多个数组

来自分类Dev

在多个数组中复制一个对象数组

来自分类Dev

推到一个数组阵列,其具有一个数组的数组

来自分类Dev

过滤对象数组,其中一个对象的数组与另一个数组至少有一个匹配项

来自分类Dev

柴期望:一个数组包含至少具有这些属性和值的对象

来自分类Dev

根据包含来自另一个数组的所有值的数组属性过滤对象数组

来自分类Dev

用多个数组组成一个对象

来自分类Dev

用多个数组组成一个对象

来自分类Dev

使用另一个数组中的特定值过滤多个数组

来自分类Dev

如何基于另一个对象ID数组过滤具有MongoDB对象ID的对象数组?

来自分类Dev

将具有多个分隔符的String列拆分为一个数组

来自分类Dev

javascript:使用另一个数组作为过滤器过滤对象数组

来自分类Dev

具有多个数组的 JSON 对象

来自分类Dev

如何从一个数组中获得具有其他属性的对象?

来自分类Dev

如何使用localstorage和Jquery从多个单击事件中生成一个具有存储值数组的对象键

来自分类Dev

比较两个具有对象的数组,并从第一个数组中删除重复项

来自分类Dev

从具有多个匹配对象的数组中删除一个对象

来自分类Dev

setState一个数组和对象

来自分类Dev

在一个数组中有多个值-For循环?

来自分类Dev

一个数组中有多个变量?

来自分类Dev

合并多个数组(对象)并与另一个数组进行比较

来自分类Dev

使用 Node JS 将多个数组转换为对象到一个数组

来自分类Dev

如何在JavaScript中从一个数组过滤另一个数组的对象?

来自分类Dev

用另一个数组过滤一个数组并创建新对象?

Related 相关文章

  1. 1

    为什么过滤具有多个条件的对象数组会返回一个空数组?

  2. 2

    在javascript中基于具有多个数组的另一个对象的过滤来过滤数组

  3. 3

    通过具有重复键的另一个数组过滤对象数组

  4. 4

    用一个条件过滤多个数组

  5. 5

    使用内部数组和另一个数组过滤对象数组

  6. 6

    在一个数组中合并具有相同键值的多个数组

  7. 7

    在多个数组中复制一个对象数组

  8. 8

    推到一个数组阵列,其具有一个数组的数组

  9. 9

    过滤对象数组,其中一个对象的数组与另一个数组至少有一个匹配项

  10. 10

    柴期望:一个数组包含至少具有这些属性和值的对象

  11. 11

    根据包含来自另一个数组的所有值的数组属性过滤对象数组

  12. 12

    用多个数组组成一个对象

  13. 13

    用多个数组组成一个对象

  14. 14

    使用另一个数组中的特定值过滤多个数组

  15. 15

    如何基于另一个对象ID数组过滤具有MongoDB对象ID的对象数组?

  16. 16

    将具有多个分隔符的String列拆分为一个数组

  17. 17

    javascript:使用另一个数组作为过滤器过滤对象数组

  18. 18

    具有多个数组的 JSON 对象

  19. 19

    如何从一个数组中获得具有其他属性的对象?

  20. 20

    如何使用localstorage和Jquery从多个单击事件中生成一个具有存储值数组的对象键

  21. 21

    比较两个具有对象的数组,并从第一个数组中删除重复项

  22. 22

    从具有多个匹配对象的数组中删除一个对象

  23. 23

    setState一个数组和对象

  24. 24

    在一个数组中有多个值-For循环?

  25. 25

    一个数组中有多个变量?

  26. 26

    合并多个数组(对象)并与另一个数组进行比较

  27. 27

    使用 Node JS 将多个数组转换为对象到一个数组

  28. 28

    如何在JavaScript中从一个数组过滤另一个数组的对象?

  29. 29

    用另一个数组过滤一个数组并创建新对象?

热门标签

归档