JavaScript根据多个数组过滤对象

时间:2019-12-18 17:02:26

标签: javascript arrays filter

我想基于一组包含过滤条件的数组来过滤对象。它基本上可以工作,直到其中一个过滤器数组包含多个项。这是代码:

// the filters
const filters = {
	"eyeColor": ["blue"],
	"gender": ["male"],
	"age": ["33"],
	"tags": ["d3js", "vuejs"] // multiple terms in the filter array breaks the code (returns empty array)
}

// the data 
const users = [
	{
		"age": "33",
		"eyeColor": "blue",
		"tags": "d3js, max, grotesk",
		"gender": "male",
	},
	{
		"age": "31",
		"eyeColor": "blue",
		"tags": "vuejs, adrian,  serif",
		"gender": "male",
	},
	{
		"age": "37",
		"eyeColor": "brown",
		"tags": "vuejs, max,  mono, d3js",
		"gender": "female",
	},
	{
		"age": "33",
		"eyeColor": "blue",
		"tags": "vuejs, markus, grotesk",
		"gender": "male",
	},
]

// the filter function
let results = users.filter(function (object) {
	return Object.entries(filters).every(function ([key, value]) {		
		return value.every(function (filter) {
			return object[key].includes(filter)
		})
	})
});
console.log(results);

我得到一个空数组,而预期结果将是:

{
   "age": "33",
   "eyeColor": "blue",
   "tags": "d3js, max, grotesk",
   "gender": "male",
},
{
    "age": "33",
    "eyeColor": "blue",
    "tags": "vuejs, markus, grotesk",
    "gender": "male",
}

如何获得预期的结果?

1 个答案:

答案 0 :(得分:2)

代码使用

return value.every(function (filter) ...
//           ^^^^^

,但是您不希望匹配允许数组中所有标签的 all ,仅匹配some any ):

return value.some(function (filter) ...
//           ^^^^

这是一个示范:

const filters = { "eyeColor": ["blue"], "gender": ["male"], "age": ["33"], "tags": ["d3js", "vuejs"] }
const users = [{ "age": "33", "eyeColor": "blue", "tags": "d3js, max, grotesk", "gender": "male", }, { "age": "31", "eyeColor": "blue", "tags": "vuejs, adrian,  serif", "gender": "male", }, { "age": "37", "eyeColor": "brown", "tags": "vuejs, max,  mono, d3js", "gender": "female", }, { "age": "33", "eyeColor": "blue", "tags": "vuejs, markus, grotesk", "gender": "male", }, ];

const filterEntries = Object.entries(filters);
const results = users.filter(user =>
  filterEntries.every(([key, permitted]) =>
    permitted.some(e => user[key].includes(e))
  )
);
console.log(results);