如何基于数组中的对象数组过滤数组

时间:2020-04-03 18:33:15

标签: javascript arrays reactjs

我有一个称为allLeads的对象数组。每个对象都有另一个对象数组,称为引线。现在,我有一个搜索栏,用户可以在其中键入任何内容,还有一个名为onChange的函数,该函数将检查数组中四个不同项目中的搜索值-LeadName,它位于所有对象和currentCompany的顶层, LeadActivity和状态位于Leads数组中的对象内部。在Leads数组中,如果用户在搜索栏中写入linkedin,则只会返回以currentCompany作为linkedin的对象,而不是带有Google的对象。我需要以某种方式找出一种基于这四个参数返回数组对象的方法,但是到目前为止我所做的任何尝试都失败了。如果我重复了这个问题,请原谅我,因为到目前为止我还没有找到任何类似的查询。

//Array to search

const allLeads = [
{
leadName: 'react',
leads: [
  {
    currentCompany: 'linkedin',
    leadActivity: 'messaged',
    status: 'connected'
  },
  {
    currentCompany: 'google',
    leadActivity: 'messaged',
    status: 'not connected'
  }
],
leadId: '555',
userId: '555'
},
{
leadName: 'angular',
leads: [
  {
    currentCompany: 'walmart',
    leadActivity: 'messaged',
    status: 'connected'
  },
  {
    currentCompany: 'amazon',
    leadActivity: 'not messaged',
    status: 'not connected'
  },
],
leadId: '666',
userId: '666'
}
]

到目前为止,我尝试过的是此操作,但它不适用于过滤器内部的过滤器。不适用于地图内的过滤器。

export const searchLeads = (allLeads, value) => {
 const newLeads = allLeads.filter(({ leadName, leads }) => {
  leads.filter(({ currentCompany, leadActivity, status }) => {
    return (
      filterItem(leadName, value)
      ||
      filterItem(currentCompany, value)
      ||
      filterItem(leadActivity, value)
      ||
      filterItem(status, value)
    );
  })
  return newLeads;
}
 )};

const filterItem = (item, itemToCheck) => {
if(item.toLowerCase().includes(itemToCheck.toLowerCase())) return true;
else return false;
}

3 个答案:

答案 0 :(得分:0)

可以重组对象吗?我认为您的复杂性源于您以非常复杂(嵌套)的方式组织对象的事实。

我会很简单:

simplerArrayOfObj =
[{ leadname:'whatever', currentCompany:'whatever', leadActivity:'', status:'whatever'},
{ leadname:'whatever', currentCompany:'whatever', leadActivity:'', status:'whatever'}]

有一个问题:

   const newArrayFiltered = function search(leadname, currentCompany, leadActivity, status){
    //validate the fields first
    // ...more code
     return simplerArrayOfObj.filter(arr=> arr.leadname === leadname || arr.currentCompany === currentCompany || arr.leadActivity === leadActivity || arr.status === status)
    }

有了这个新数组newArrayFiltered,您可以做所有想要的深层工作。

答案 1 :(得分:0)

Array.prototype.filter将返回一个数组。在allLeads.filter中,您从不返回任何内容,因此它永远不知道特定项目是否满足该条件。

要查看哪些项目符合您的条件,建议将leads.filter(({ currentCompany, leadActivity, status }) => {更改为return leads.filter(({ currentCompany, leadActivity, status }) => {

也将allLeads.filter(({ leadName, leads }) => {更改为带有allLeads.map(({ leadName, leads }) => {的地图

那会给你一个数组数组。如果您想弄平它,可以使用lodash或类似的东西:

const flattenedArray = arrayOfArrays.reduce((acc, arr) => {
  return acc.concat(arr);
}, []);

答案 2 :(得分:0)

以下是您需要的内容的摘要 https://jsbin.com/zeyomidafa/edit?js,console

const allLeads = [
  {
    leadName: 'react',
    leads: [
    {
      currentCompany: 'linkedin',
      leadActivity: 'messaged',
      status: 'connected'
    },
    {
      currentCompany: 'google',
      leadActivity: 'messaged',
      status: 'not connected'
    }
    ],
    leadId: '555',
    userId: '555'
  },
  {
    leadName: 'angular',
    leads: [
      {
        currentCompany: 'walmart',
        leadActivity: 'messaged',
        status: 'connected'
      },
      {
        currentCompany: 'amazon',
        leadActivity: 'not messaged',
        status: 'not connected'
      },
    ],
    leadId: '666',
    userId: '666'
  }
]


function filter(aleads, q){
  // map the list and only keep leads matching the query
  let aleadsDeepFilter = aleads.map(
     function(oneLead){
       return {
         ...oneLead,
         leads: oneLead.leads.filter(
           function(_lead){
             return (_lead.status === q) || (_lead.leadActivity === q) || (_lead.currentCompany === q)
           }
         )
       }
     }
  );

  // second filter, return items that have leads left from previous filter + matching the leadName
  aleadsDeepFilter = aleadsDeepFilter.filter(
    function(oneLead){
      return (oneLead.leadName === q) || (oneLead.leads.length > 0)
    }
  )

  return aleadsDeepFilter;

}


console.log(filter(allLeads, "angular"))
console.log(filter(allLeads, "google"))