问题
I need to filter array of object by another array of object without knowledge of exact properties in criterias array. Let's take a look to example for better understanding.
Here is an array that I need to filter
const dataset = [
{
id: "4",
someval1: "10",
someval2: "20",
someval3: "30",
someval4: "40"
},
{
id: "10",
someval1: "10",
someval2: "20",
someval3: "30",
someval4: "40"
},
{
id: "22",
someval1: "102",
someval2: "202",
someval3: "302",
someval4: "40"
}];
Here is an array which has values that are supposed to be filter condition for first array
const criterias = [{ someval1: "10" }, { someval3: "30" }, { someval4: "40" }];
So whenever object in dataset contains all values from criterias I want to keep him. Problem is that I want objects in dataset to be filtered by all criterias that are equal.
So far I was able to get this script which filters dataset correctly but only by one criteria. So from given arrays after filtering I should get only first two objects from dataset, third one does not meat all criterias.
Here is my current script
const dataset = [
{
id: "4",
someval1: "10",
someval2: "20",
someval3: "30",
someval4: "40"
},
{
id: "10",
someval1: "10",
someval2: "20",
someval3: "30",
someval4: "40"
},
{
id: "22",
someval1: "102",
someval2: "202",
someval3: "302",
someval4: "40"
}];
const criterias = [{ someval1: "10" }, { someval3: "30" }, { someval4: "40" }];
const filter = dataset.filter(item => criterias.some(criteria => Object.keys(criteria).some(prop => item[prop] != criteria[prop])));
console.log(filter)
Thanks for all suggestions in advance.
回答1:
You could get the entries of the condensed object and use Array#every and check the properties with the values.
var dataset = [{ id: "4", someval1: "10", someval2: "20", someval3: "30", someval4: "40" }, { id: "10", someval1: "10", someval2: "20", someval3: "30", someval4: "40" }, { id: "22", someval1: "102", someval2: "202", someval3: "302", someval4: "40" }],
criterias = [{ someval1: "10" }, { someval3: "30" }, { someval4: "40" }],
filters = Object.entries(Object.assign({}, ...criterias)),
result = dataset.filter(o => filters.every(([k, v]) => o[k] === v));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
回答2:
You can use Array.filter() and Array.every():
Array.filter()will filter the matched object and put those in a new array.Array.every()will be used for checking that every object incriteriasarray satisfies the object ofdataset. Since there could be any name for the object key in object ofcriteriasarray, you can useObject.keys()[0]to get that particular key as you only have one key in each object ofcriteriasarray.
const dataset = [{
id: "4",
someval1: "10",
someval2: "20",
someval3: "30",
someval4: "40"
},
{
id: "10",
someval1: "10",
someval2: "20",
someval3: "30",
someval4: "40"
},
{
id: "22",
someval1: "102",
someval2: "202",
someval3: "302",
someval4: "40"
}
];
const criterias = [{
someval1: "10"
}, {
someval3: "30"
}, {
someval4: "40"
}];
let result = dataset.filter((datasetObj) => criterias.every((criteria) => criteria[Object.keys(criteria)[0]] === datasetObj[Object.keys(criteria)[0]]));
console.log(result);
回答3:
You need to use Array.prototype.every for the criterias array to check and validate all the criteria objects to the item in the dataset:
var dataset = [
{
id: "4",
someval1: "10",
someval2: "20",
someval3: "30",
someval4: "40"
},
{
id: "10",
someval1: "10",
someval2: "20",
someval3: "30",
someval4: "40"
},
{
id: "22",
someval1: "102",
someval2: "202",
someval3: "302",
someval4: "40"
}];
var criterias = [{ someval1: "10" }, { someval3: "30" }, { someval4: "40" }];
var res = dataset.filter(item =>
criterias.every(criteria =>
Object.keys(criteria).every(prop =>
item[prop] == criteria[prop])));
console.log(res)
来源:https://stackoverflow.com/questions/58133504/how-filter-array-of-objects-by-another-array-of-objects-es6