Javascript 如何基于两个过滤器过滤对象数组?

Javascript 如何基于两个过滤器过滤对象数组?,javascript,arrays,Javascript,Arrays,我有一组对象: const myArr = [{ name: 'A', type: 1, subtype: 1 }, { name: 'B', type: 1, subtype: 2 }, { name: 'C', type: 2, subtype: 3 }, { name: 'D', type: 3, subtype: 1, }]; 然后我有两个变量,每个变量都有一个ID。它们是typeId和subsubfid。它们可以是与上面数组中的类型和子

我有一组对象:

const myArr = [{
  name: 'A',
  type: 1,
  subtype: 1
},
{
  name: 'B',
  type: 1,
  subtype: 2
},
{
  name: 'C',
  type: 2,
  subtype: 3
},
{
  name: 'D',
  type: 3,
  subtype: 1,
}];
然后我有两个变量,每个变量都有一个ID。它们是
typeId
subsubfid
。它们可以是与上面数组中的类型和子类型匹配的数值,也可以是
-1
,表示“全部”

因此,我将展示一些情况以及过滤器应返回的内容:

type: 1 | subtype: 1 --> A
type: -1 | subtype: -1 --> ABCD
type: 1 | subtype: -1 --> AB
type: 2 | subtype: 3 --> C
type: 2 | subtype: 2 --> nothing
type: 3 | subtype: 1 --> D
你明白了

const filteredData = data.filter(item => {
    const { typeId, subtypeId } = getCurrentFilterIds();

    if(typeId === -1) return true;
    if(typeId !== -1){
      if(subtypeId === -1) return item.type === typeId;
      if(subtypeId !== -1) return item.type === typeId && item.subtype === subtypeId;
    }
  });

我提出了这个函数,但也许有更好的方法?

您可以直接将条件作为表达式,而不是使用
if
语句

const
过滤器=(数组,类型ID,子类型ID)=>array.filter(o=>
类型ID==-1||
o、 类型===类型ID&(子类型ID===-1 | | o.subtype===子类型ID)
),
数据=[{name:'A',type:1,subtype:1},{name:'B',type:1,subtype:2},{name:'C',type:2,subtype:3},{name:'D',type:3,subtype:1}];
console.log(过滤器(数据,1,1));//A.
日志(过滤器(数据,-1,-1));//A、B、C、D
console.log(过滤器(数据,1,-1));//A B
console.log(过滤器(数据,2,3));//C
console.log(过滤器(数据,2,2));//[]
console.log(过滤器(数据,3,1));//D

.as控制台包装{max height:100%!important;top:0;}
如注释中所述,您不希望为列表中的每个项目调用GetCurrentFilterId()。因此,应该将其移到过滤器功能之外

你的ifs有点多余和不必要。你可以用if-else来代替。但在这种情况下,由于如果第一条语句为true,则返回一个值,因此也不需要else语句。因此,您可以简单地执行以下操作:

const { typeId, subtypeId } = getCurrentFilterIds();
const filteredData = data.filter(item => {
    if (typeId === -1) return true;
    if (subtypeId === -1) return item.type === typeId;
    return item.type === typeId && item.subtype === subtypeId;
});
您甚至可以更进一步,在一行中返回结果,并去掉所有的if

const { typeId, subtypeId } = getCurrentFilterIds();
const filteredData = data.filter(item => {
    return (typeId === -1) || ((item.type === typeId) && (subtypeId === -1 || item.subtype === subtypeId));
});

对于给定的x,无论是在
类型
上还是在
子类型
上,对属性的检查都是相同的:

  • 如果x为-1,则任何属性值都可以
  • 否则,属性值必须等于x
因此,我们可以通过以下方式将其正式化:

constpropcheck=(k,x)=>o=>x==-1?真:o[k]==x;
//                 ^  ^     ^  
//                 1  2     3
//1:属性名称,例如“类型”或“子类型”
//2:x例如-1或2
//3:从中读取属性的对象
我们可以编写一个和函数,该函数取两个函数,然后取一个值,将这两个函数应用于它,如果两者都有,则返回true:

const和=(f,g)=>x=>f(x)和&g(x);
获取您的
typeId
subsubfid
并将它们传递给相应的
propCheck
调用。e、 g

myArr.filter(和(propCheck('type',2),propCheck('subtype',3));
//=>[{名称:“C”,类型:2,子类型:3}]
myArr.filter(和(propCheck('type',2),propCheck('subtype',2));
//=> []
myArr.filter(and(propCheck('type',1),propCheck('subtype',-1));
//=>[{name:“A”,类型:1,子类型:1}
//=>,{name:“B”,类型:1,子类型:2}]

您应该将
GetCurrentFilterId()
的调用移出
数组。filter
调用,否则将为数据数组中的每个项调用它。当
typeId
-1
SubsubId
不是时,情况如何?第二个选项的可读性要差得多