Javascript 如何基于另一个具有条件的数组对对象数组进行排序

Javascript 如何基于另一个具有条件的数组对对象数组进行排序,javascript,arrays,object,Javascript,Arrays,Object,有人能帮我知道如何根据另一个包含多个条件的数组过滤对象数组吗 样本阵列 const arrayToFilter = [ { name: 'Renaldo Ca', screen_name: 'rca0', followers_count: 726, following_count: 752, location: 'Peru', verified: true, }, { name: 'Bobbette Dibling',

有人能帮我知道如何根据另一个包含多个条件的数组过滤对象数组吗

样本阵列

const arrayToFilter = [
  {
    name: 'Renaldo Ca',
    screen_name: 'rca0',
    followers_count: 726,
    following_count: 752,
    location: 'Peru',
    verified: true,
  },
  {
    name: 'Bobbette Dibling',
    screen_name: 'bdibling1',
    followers_count: 747,
    following_count: 613,
    location: 'Argentina',
    verified: true,
  },
  {
    name: 'Obed Snelson',
    screen_name: 'osnelson2',
    followers_count: 466,
    following_count: 352,
    location: 'Russia',
    verified: false,
  },
  {
    name: 'Elyssa Eastop',
    screen_name: 'eeastop3',
    followers_count: 888,
    following_count: 493,
    location: 'Uganda',
    verified: true,
  },
  {
    name: 'Auroora Balogun',
    screen_name: 'abalogun4',
    followers_count: 688,
    following_count: 468,
    location: 'Brazil',
    verified: true,
  },
  {
    name: 'Sarge Crosser',
    screen_name: 'scrosser5',
    followers_count: 218,
    following_count: 424,
    location: 'United Kingdom',
    verified: true,
  },
  {
    name: 'Griswold Lardeur',
    screen_name: 'glardeur6',
    followers_count: 785,
    following_count: 122,
    location: 'South Korea',
    verified: false,
  },
  {
    name: 'Edwin Goodlatt',
    screen_name: 'egoodlatt7',
    followers_count: 484,
    following_count: 611,
    location: 'Indonesia',
    verified: true,
  }
]
具有筛选条件的数组:

const conditions=[ 
    { 
        id: 'name', 
        operator: 'CONTAINS' 
        value: 'Bob', 
    },
    { 
        condition:'AND',
        id: 'followers_count', 
        operator: 'GTE' 
        value: 200, 
    }, 
    {
        condition:'AND',
        id: 'following_count', 
        operator: 'LTE' 
        value: 10,
    },
    {
        condition:'OR',
        id: 'verified', 
        operator: 'EQ' 
        value: true,
    } 
  ]
下面的代码给出了过滤后的数组,但给出了和/或执行messesup的逻辑

   const filterWithConditions = (arr, conditions) =>
      arr.filter((item) =>
        conditions.every(({ id, operator, value }) => {
          switch (operator) {
            case 'CONTAINS':
              return item[id].toLowerCase().indexOf(value.toLowerCase()) > -1;
            case 'GTE':
              return item[id] >= value;
            case 'LTE':
              return item[id] <= value;
            case 'EQ':
              return item[id].toString() === value.toString();
            default:
              return false;
          }
        })
      );
    
    
    let filteredData = filterWithConditions(data, filters);
    
    const alternateFilters = groupBy(filters, 'condition')['OR'];
    if (alternateFilters) alternateFilters.map((filter) => filteredData.push(...filterWithConditions(data, [filter])));
    const processedData = getUniqData(filteredData);
const filterWithConditions=(arr,conditions)=>
arr.filter((项目)=>
条件.every({id,运算符,值})=>{
开关(操作员){
案例“包含”:
返回项[id].toLowerCase().indexOf(value.toLowerCase())>-1;
案例“GTE”:
返回项[id]>=值;
案例“LTE”:
返回项[id]Filteredata.push(…filterWithConditions(数据,[filter]));
const processedData=getUniqData(filteredData);
该代码还应返回基于这些条件对按位条件进行过滤的数组(和/或)。 请让我知道这个优化的代码。提前谢谢

代码沙盒链接:

const items=[
{
姓名:“奥贝德·鲍勃·斯内尔森”,
屏幕名称:“osnelson2”,
追随者人数:466,
以下数字:352,
地点:'俄罗斯',
核实:假,
},
{
名称:'Elyssa Eastop',
屏幕名称:“eeastop3”,
追随者数量:888,
以下数字:493,
地点:'乌干达',
核实:对,,
},
]
常量条件=[
{ 
id:'名称',
运算符:“包含”,
值:“鲍勃”
},
{ 
条件:'和',
id:'追随者计数',
操作员:“GTE”,
价值:200
}
];
const conditionCount=conditions.length
const itemscont=items.length;
常量结果=[];
for(让index=0;index=conditions[index][value']
结果.推送(项目[itemsIndex])
打破
}
}
}
控制台日志(结果);

我没有包括所有的运算符,但是嘿……你应该能够自己计算出其余的运算符,我想:)。这与我提出的想法有关。

我猜逻辑应该是这样应用的:

Where the name contains bob
 AND the followers count is gte 200

Where the name contains bob
 AND the following count is lte 400

Where the name contains bob
 OR the verified property is true
基于上述假设,我会这样做:

const result = (item,condition) => {
  switch(condition.operator) {
    case 'CONTAINS': return item[condition.id].contains(condition.value);
    case 'GTE': return item[condition.id] >= condition.value;
    case 'LTE': return item[condition.id] <= condition.value;
    default: return false;
  }
}

const results = arrayToFilter.filter(item => {
  const baseCondition = conditions[0];
  const baseResult = result(item,baseCondition);

  // if there's only one condition, early return
  if(conditions.length === 1) return baseCondition;

  return conditions.slice(1).some(c => {
     const r = result(item,c);

     switch(c.condition) {
       case 'AND': return baseCondition && r;
       case 'OR': return baseCondition || r;
       default: return false;
     }

  });


});
const result=(项目、条件)=>{
开关(条件操作员){
案例“包含”:返回项[condition.id]。包含(condition.value);
案例“GTE”:返回项[condition.id]>=condition.value;
案例“LTE”:返回项[condition.id]{
const baseCondition=条件[0];
const baseResult=结果(项,baseCondition);
//如果只有一个条件,请提前返回
if(conditions.length==1)返回baseCondition;
返回条件.slice(1).some(c=>{
常数r=结果(项目c);
开关(c状态){
案例“AND”:返回baseCondition&&r;
案例“OR”:返回基本条件| | r;
默认:返回false;
}
});
});

尽管如此,UI还是令人困惑的,应该包括嵌套条件的功能,以使其更清晰。

我做了一个小示例。根据您的需要进行更改。我添加了一些注释以供您理解

//初始数据
常量objs=[
{
a:“a”,
b:“b”,
c:“c”
},
{
a:“a b a”,
b:“b”,
c:“c”
},
{
a:“a c”,
b:“b c”,
c:“c”
},
{
a:“a b”,
b:“b c”,
c:“c”
},
];
常数条件={
“like”:(a,b)=>a.包括(b),
“等式”:(a,b)=>a==b
};
警察行动={
“或”:(a,b)=>a | | b,
“和”:(a,b)=>a&&b
}
常数qrys=[
{
上校:“a”,
赖斯:“像”,
瓦尔:“b”
},
{
上校:“b”,
条件:“情商”,
瓦尔:“b c”,
作品:“和”
},
{
上校:“c”,
条件:“情商”,
瓦尔:“b c”,
作品:“或”
},
{
上校:“c”,
条件:“情商”,
瓦尔:“c”,
作品:“和”
}
]
//作用
const filtered=objs.filter(obj=>{
设ret=false;
for(数量单位为数量单位){
//对象的实际值
const val=对象[qry.col];
//将其与给定条件下的期望值进行比较
const assert=conds[qry.cond](val,qry.val);
//应用逻辑运算符。
如果(qry.op){
ret=ops[qry.op](ret,assert);
}否则{
ret=断言;
}
}
返回ret;
});

console.log(过滤);
您可以构建一个字符串,并使用正确的逻辑运算符对数据执行
eval

const
ops={
等式:(a,b)=>a==b,
GTE:(a,b)=>a>=b,
LTE:(a,b)=>a.toLowerCase()。包括(b.toLowerCase()),
和:(a,b)=>a&&b,
或者:(a,b)=>a | | b
},
filterBy=filters=>o=>filters.reduce((r,{condition,id,operator,value})=>(ops[condition]| | ops.OR)(r,ops[operator](o[id],value)),false),
数据=[{name:'Renaldo Ca',screen_name:'rca0',followers_count:726,followers_count:752,location:'Peru',verified:false},{name:'Bobbette Dibling',screen_name:'bdibling1',followers_count:747,followers_count:613,location:'argenta',verified:true},{name:'Obed Snelson',screen_name:'osnelson 2',follower_count:466,follower_count:352,地点:'rusia',verified:false},{name:'Elyssa Eastop',screen_name:'eeastop3',followers_count:888,follower_count:493,地点:'乌干达',verified:true},{姓名:'Auroora Balogun',屏幕名称:'abalogun4',追随者人数:688,跟随人数:468,地点:'Brazil',验证:true},{姓名:'Sarge Crosser',屏幕名称:'scrosser5',追随者人数:218,跟随人数:424,地点:'United Kingdom',验证:true},{名称:'Griswold Lardeur',屏幕名称:'glardeur6',追随者人数:785,追随者人数:122,位置:
const result = (item,condition) => {
  switch(condition.operator) {
    case 'CONTAINS': return item[condition.id].contains(condition.value);
    case 'GTE': return item[condition.id] >= condition.value;
    case 'LTE': return item[condition.id] <= condition.value;
    default: return false;
  }
}

const results = arrayToFilter.filter(item => {
  const baseCondition = conditions[0];
  const baseResult = result(item,baseCondition);

  // if there's only one condition, early return
  if(conditions.length === 1) return baseCondition;

  return conditions.slice(1).some(c => {
     const r = result(item,c);

     switch(c.condition) {
       case 'AND': return baseCondition && r;
       case 'OR': return baseCondition || r;
       default: return false;
     }

  });


});