使用可用或不使用筛选器筛选对象数组



假设我有这个数据集:

const data = [ 
{animal: 'cat', name: 'mu', year: 2016},
{animal: 'cat', name: 'muji', year: 2021},
{animal: 'cat', name: 'mine', year: 2021},
{animal: 'dog', name: 'fido', year: 2000}, 
{animal: 'hamster', name: 'gerry', year: 2020}, 
{animal: 't-rex', name: 'dino', year: 2020}, 
{animal: 'sheep', name: 's', year: 2019}, 
{animal: 'sheep', name: 'sss', year: 2016}, 
]

我想用一些值来过滤它,例如用animalyear。我能做的很简单:

const animal = 'sheep'
const year = 2019
const filteredData = data.filter(d => d.animal === animal && d.year === year)
// result
const filteredData = [ 
{animal: 'sheep', name: 's', year: 2019}, 
]

此处相同:

const animal = 'cat'
const year = 2021
const filteredData = [ 
{animal: 'cat', name: 'muji', year: 2021},
{animal: 'cat', name: 'mine', year: 2021},
]

我的问题是,有时animalyear可以是null。在这种情况下,我不希望按该值进行筛选。例如,这些是我想要获得的:

const animal = 'cat'
const year = null
const filteredData = [ 
{animal: 'cat', name: 'mu', year: 2016},
{animal: 'cat', name: 'muji', year: 2021},
{animal: 'cat', name: 'mine', year: 2021},
]
// ---
const animal = null
const year = 2020
const filteredData = [ 
{animal: 'hamster', name: 'gerry', year: 2020}, 
{animal: 't-rex', name: 'dino', year: 2020},
]
// ---
const animal = null
const year = null
const filteredData = [ 
{animal: 'cat', name: 'mu', year: 2016},
{animal: 'cat', name: 'muji', year: 2021},
{animal: 'cat', name: 'mine', year: 2021},
{animal: 'dog', name: 'fido', year: 2000}, 
{animal: 'hamster', name: 'gerry', year: 2020}, 
{animal: 't-rex', name: 'dino', year: 2020}, 
{animal: 'sheep', name: 's', year: 2019}, 
{animal: 'sheep', name: 'sss', year: 2016}, 
]

我该怎么做?

注意,这只是一个简单的例子,在我的情况下,我可以有两个以上的变量作为过滤器

您可以使用Nullish合并运算符并使用过滤器作为

d.animal === (animal ?? d.animal)

const data = [
{ animal: "cat", name: "mu", year: 2016 },
{ animal: "cat", name: "muji", year: 2021 },
{ animal: "cat", name: "mine", year: 2021 },
{ animal: "dog", name: "fido", year: 2000 },
{ animal: "hamster", name: "gerry", year: 2020 },
{ animal: "t-rex", name: "dino", year: 2020 },
{ animal: "sheep", name: "s", year: 2019 },
{ animal: "sheep", name: "sss", year: 2016 },
];
const animal = null;
const year = null;
const filteredData = data.filter(
(d) => d.animal === (animal ?? d.animal) && d.year === (year ?? d.year)
);
console.log(filteredData);

正如您所写的">我可以有两个以上的变量作为过滤器…";,我认为硬编码过滤表达式不是一个好主意。此外,如果您的数据和过滤器都是动态的(如果事先不知道属性(,则这甚至是不可能的。相反,你可以使用这样的方法:

const data = [
{ animal: 'cat', name: 'mu', year: 2016 },
{ animal: 'cat', name: 'muji', year: 2021 },
{ animal: 'cat', name: 'mine', year: 2021 },
{ animal: 'dog', name: 'fido', year: 2000 },
{ animal: 'hamster', name: 'gerry', year: 2020 },
{ animal: 't-rex', name: 'dino', year: 2020 },
{ animal: 'sheep', name: 's', year: 2019 },
{ animal: 'sheep', name: 'sss', year: 2016 }
];
const query = { animal: 'cat', year: null };
// remove all null values
// https://stackoverflow.com/a/38340730
const q = Object.fromEntries(Object.entries(query).filter(([_, v]) => v != null));
// https://stackoverflow.com/a/61676007
const isSubset = (superObj, subObj) => {
return Object.keys(subObj).every(ele => {
if (typeof subObj[ele] == 'object') return isSubset(superObj[ele], subObj[ele]);
return subObj[ele] === superObj[ele];
});
};
const filteredData = data.filter(d => isSubset(d, q));
console.log(filteredData);

这将是我解决这个问题的第一枪(请参阅代码中的注释(:

const data = [{animal: 'cat', name: 'mu', year: 2016}, {animal: 'cat', name: 'muji', year: 2021}, {animal: 'cat', name: 'mine', year: 2021}, {animal: 'dog', name: 'fido', year: 2000},  {animal: 'hamster', name: 'gerry', year: 2020},  {animal: 't-rex', name: 'dino', year: 2020},  {animal: 'sheep', name: 's', year: 2019},  {animal: 'sheep', name: 'sss', year: 2016}];
// Instead of using filter literals, use a filter object:
const filter = { animal: 'dog',  year: null };
// Then, for filtering, write your own filter function:
const filterAnimals = (arr, filters) => arr
.filter(animal => Object.entries(filters)
.filter(([key, value]) => value !== null) // removes filter properties equaling null
.every(([key, value]) => animal[key] === value));
console.log(filterAnimals(data, filter));

最新更新