JavaScript对象数组:通过多个AND条件进行筛选

3

我的模拟数据:

[
  {
    "id": 1,
    "first_name": "Suzy",
    "last_name": "Pinnell",
    "email": "spinnell0@utexas.edu",
    "gender": "Agender",
    "image": "http://dummyimage.com/410x239.png/5fa2dd/ffffff",
    "department": "Marketing",
    "job_title": "Quality Control Specialist",
    "skill": "Residential Homes"
   },
  {
    "id": 2,
    "first_name": "Enriqueta",
    "last_name": "Folbig",
    "email": "efolbig1@google.com.br",
    "gender": "Male",
    "image": "http://dummyimage.com/247x244.png/5fa2dd/ffffff",
    "department": "Sales",
    "job_title": "Environmental Specialist",
    "skill": "MMC"
  },
  {
    "id": 3,
    "first_name": "Simmonds",
    "last_name": "Acomb",
    "email": "sacomb2@amazon.co.uk",
    "gender": "Polygender",
    "image": "http://dummyimage.com/315x256.png/dddddd/000000",
    "department": "Human Resources",
    "job_title": "Accountant",
    "skill": "Xilinx"
  },
  {
    "id": 4,
    "first_name": "Bernita",
    "last_name": "Hartman",
    "email": "bhartman3@whitehouse.gov",
    "gender": "Female",
    "image": "http://dummyimage.com/305x275.png/dddddd/000000",
    "department": "Support",
    "job_title": "Account ExecutiveII",
    "skill": "Airframe"
  }
]

我在这里找到了一个类似的问题:javascript filter array multiple conditions

为了定义筛选条件,他们传递了一个对象:

var filter = {
  gender: 'male',
  department: 'Sales'
};

这个代码可以正常运行。它展示了每个同时包含这两个键的对象。

+我试图对它进行修改,以便能够使用一个数组:*

var filter = {
  gender: ['Male'],
  department: ['Sales', 'Marketing']
};

我的目标是根据数组中给定的值过滤数据。只有包含销售和市场营销中所有男性员工的项才应该出现。

我尝试了使用 includes(在 filter 和 for-in 循环内部),但它仅显示第一个数组的结果,第二个被忽略了。我不确定如何在所有数组中实现 AND 条件。

谢谢。

5个回答

1

试试这个

var itemsFilter = {
  gender: ['Male'],
  department: ['Sales', 'Marketing']
};
users= users.filter (function(item) {
  var find=false;
  for (var key in itemsFilter) {
   find=false;
   if (item[key] === undefined) return false;
    for (var k in itemsFilter[key]) 
      if (itemsFilter[key][k] == item[key]) find=true;
      if (find==false) return false;
   };
return find;
});

1

不要使用===运算符的否定形式,可以使用includes方法的否定形式:

data = data.filter(function(item) {
  for (var key in filter) {
    if (item[key] === undefined || !filter[key].includes(item[key]))
      return false;
  }
  return true;
});

我试过了,但没用。如果数组中有多个项,则根本没有结果。这个可以:var filter = { gender: ['Male'], department: ['Sales'] };这个不行:var filter = { gender: ['Male'], department: ['Sales', 'Marketing'] }; - Vorname Nachname
@VornameNachname 哎呀,我在 || 后面交换了 filteritem。已经编辑并修复了。 - Mureinik
这给我没有结果。 - Vorname Nachname

1

这是一个很好的every使用案例 :)

const data = [
  {
    "id": 1,
    "first_name": "Suzy",
    "last_name": "Pinnell",
    "email": "spinnell0@utexas.edu",
    "gender": "Agender",
    "image": "http://dummyimage.com/410x239.png/5fa2dd/ffffff",
    "department": "Marketing",
    "job_title": "Quality Control Specialist",
    "skill": "Residential Homes"
   },
  {
    "id": 2,
    "first_name": "Enriqueta",
    "last_name": "Folbig",
    "email": "efolbig1@google.com.br",
    "gender": "Male",
    "image": "http://dummyimage.com/247x244.png/5fa2dd/ffffff",
    "department": "Sales",
    "job_title": "Environmental Specialist",
    "skill": "MMC"
  },
  {
    "id": 3,
    "first_name": "Simmonds",
    "last_name": "Acomb",
    "email": "sacomb2@amazon.co.uk",
    "gender": "Polygender",
    "image": "http://dummyimage.com/315x256.png/dddddd/000000",
    "department": "Human Resources",
    "job_title": "Accountant",
    "skill": "Xilinx"
  },
  {
    "id": 4,
    "first_name": "Bernita",
    "last_name": "Hartman",
    "email": "bhartman3@whitehouse.gov",
    "gender": "Female",
    "image": "http://dummyimage.com/305x275.png/dddddd/000000",
    "department": "Support",
    "job_title": "Account ExecutiveII",
    "skill": "Airframe"
  }
]

const filter = {
  gender: ['Male'],
  department: ['Sales', 'Marketing']
}

const result = data.filter(item => (
  Object.entries(filter).every(([key, arr]) => arr.includes(item[key]))
))

console.log(result)


1
你可以提前存储所有条目,以防止为每个数据对象获取相同的筛选器条目数组。
过滤条目以删除可能的空数组。
然后取出这些条目并检查值是否是数据中的值或者筛选器是否包含一个数组,然后检查筛选器数组是否包含来自数据的值。

const
    data = [{ id: 1, first_name: "Suzy", last_name: "Pinnell", email: "spinnell0@utexas.edu", gender: "Agender", image: "http://dummyimage.com/410x239.png/5fa2dd/ffffff", department: "Marketing", job_title: "Quality Control Specialist", skill: "Residential Homes" }, { id: 2, first_name: "Enriqueta", last_name: "Folbig", email: "efolbig1@google.com.br", gender: "Male", image: "http://dummyimage.com/247x244.png/5fa2dd/ffffff", department: "Sales", job_title: "Environmental Specialist", skill: "MMC" }, { id: 3, first_name: "Simmonds", last_name: "Acomb", email: "sacomb2@amazon.co.uk", gender: "Polygender", image: "http://dummyimage.com/315x256.png/dddddd/000000", department: "Human Resources", job_title: "Accountant", skill: "Xilinx" }, { id: 4, first_name: "Bernita", last_name: "Hartman", email: "bhartman3@whitehouse.gov", gender: "Female", image: "http://dummyimage.com/305x275.png/dddddd/000000", department: "Support", job_title: "Account ExecutiveII", skill: "Airframe" }],
    filter = { last_name: [], gender: ['Male'], department: ['Sales', 'Marketing'] },
    filterEntries = Object
        .entries(filter)
        .filter(([, v]) => !Array.isArray(v) || v.length),
    result = data.filter(o => filterEntries.every(([k, v]) =>
        o[k] === v ||
        Array.isArray(v) && v.includes(o[k])
    ));

console.log(result);


如果没有空数组,这个解决方案是可行的。 - Vorname Nachname
1
@VornameNachname,现在添加了对空数组的检查。请查看编辑。 - Nina Scholz

1

您可以通过迭代过滤器对象并在每次迭代时检查目标对象是否能够通过您的筛选器来达到预期结果(在下面的代码片段中,我使用了Object.entriesevery方法来实现这一点),如下所示:

const data = [
  {
    "id": 1,
    "first_name": "Suzy",
    "last_name": "Pinnell",
    "email": "spinnell0@utexas.edu",
    "gender": "Agender",
    "image": "http://dummyimage.com/410x239.png/5fa2dd/ffffff",
    "department": "Marketing",
    "job_title": "Quality Control Specialist",
    "skill": "Residential Homes"
   },
  {
    "id": 2,
    "first_name": "Enriqueta",
    "last_name": "Folbig",
    "email": "efolbig1@google.com.br",
    "gender": "Male",
    "image": "http://dummyimage.com/247x244.png/5fa2dd/ffffff",
    "department": "Sales",
    "job_title": "Environmental Specialist",
    "skill": "MMC"
  },
  {
    "id": 3,
    "first_name": "Simmonds",
    "last_name": "Acomb",
    "email": "sacomb2@amazon.co.uk",
    "gender": "Polygender",
    "image": "http://dummyimage.com/315x256.png/dddddd/000000",
    "department": "Human Resources",
    "job_title": "Accountant",
    "skill": "Xilinx"
  },
  {
    "id": 4,
    "first_name": "Bernita",
    "last_name": "Hartman",
    "email": "bhartman3@whitehouse.gov",
    "gender": "Female",
    "image": "http://dummyimage.com/305x275.png/dddddd/000000",
    "department": "Support",
    "job_title": "Account ExecutiveII",
    "skill": "Airframe"
  }
];

const filter = {
  gender: ['Male'],
  department: ['Sales', 'Marketing']
}

const createFilterFun = filters => obj => Object.entries(filters).every( ([k, v]) => v.includes(obj[k]) );
const filterByGenderAndDepratment = createFilterFun(filter);
const result = data.filter(filterByGenderAndDepratment);
console.log(result)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接