Javascript 基于另一个数组使用嵌套数组筛选对象数组
我有两个不同的API。第一个返回一个事件对象数组(该数据集正在增长,预计会很大)。每个事件都有一个包含字符串列表的类别数组。另一个API返回一个过滤器对象数组。每个过滤器都有一个“name”属性和一个关键字数组。在任何情况下,类别数组中包含的任何关键字都应位于此筛选器名称下。 最终目标是在屏幕上有一个过滤器列表,当用户单击过滤器时,我应该呈现该过滤器下的所有事件 事件对象示例:Javascript 基于另一个数组使用嵌套数组筛选对象数组,javascript,Javascript,我有两个不同的API。第一个返回一个事件对象数组(该数据集正在增长,预计会很大)。每个事件都有一个包含字符串列表的类别数组。另一个API返回一个过滤器对象数组。每个过滤器都有一个“name”属性和一个关键字数组。在任何情况下,类别数组中包含的任何关键字都应位于此筛选器名称下。 最终目标是在屏幕上有一个过滤器列表,当用户单击过滤器时,我应该呈现该过滤器下的所有事件 事件对象示例: { "text": { "hea
{
"text": {
"headline": "Headline example",
"text": "event description "
},
"media": {
"url": "https://www.google.com/",
"caption": "",
"credit": ""
},
"categories": [
"National",
"Canada",
"British Columbia"
]
}
{
"filters": [
{
"keywords": [
"Atlantic",
"New Brunswick",
"Newfoundland and Labrador",
"Prince Edward Island",
"Nova Scotia"
],
"name": "Atlantic"
},
{
"keywords": [
"ontario",
"Quebec"
],
"name": "Central Canada"
},
{
"keywords": [
"Manitoba",
"Saskatchewan",
"Alberta"
],
"name": "Prairie Provinces"
},
{
"keywords": [
"British Columbia"
],
"name": "West Coast"
},
{
"keywords": [
"Nunavut",
"Northwest Territories",
"Yukon Territory"
],
"name": "North"
},
{
"keywords": [
"National"
],
"name": "National"
}
]
}
过滤器对象示例:
{
"text": {
"headline": "Headline example",
"text": "event description "
},
"media": {
"url": "https://www.google.com/",
"caption": "",
"credit": ""
},
"categories": [
"National",
"Canada",
"British Columbia"
]
}
{
"filters": [
{
"keywords": [
"Atlantic",
"New Brunswick",
"Newfoundland and Labrador",
"Prince Edward Island",
"Nova Scotia"
],
"name": "Atlantic"
},
{
"keywords": [
"ontario",
"Quebec"
],
"name": "Central Canada"
},
{
"keywords": [
"Manitoba",
"Saskatchewan",
"Alberta"
],
"name": "Prairie Provinces"
},
{
"keywords": [
"British Columbia"
],
"name": "West Coast"
},
{
"keywords": [
"Nunavut",
"Northwest Territories",
"Yukon Territory"
],
"name": "North"
},
{
"keywords": [
"National"
],
"name": "National"
}
]
}
经过几天的研究,我想出了这个解决方案
function filterTimelineData(filtersObj, timelineData) {
if (!timelineData || !filtersObj) return [];
// create a new object with filters "name" as key;
const filters = Object.keys(filtersObj);
const filteredTimelineData = Object.keys(filtersObj).reduce((o, key) => ({ ...o, [key]: [] }), {});
const filteredData = timelineData.events.reduce((acc, current) => {
let filterMatch = false;
let filterMatchName = '';
for (let i = 0; i < filters.length; i++) {
filterMatch = current.categories.some(item => {
return filtersObj[filters[i]].includes(item.toLocaleLowerCase());
});
if (filterMatch && filterMatchName !== filters[i]) { // to avoid duplicated items with different categories under the same filter
filterMatchName = filters[i];
acc[filters[i]].push(current);
}
}
return acc;
}, filteredTimelineData);
return filteredData;
}
export function timelineFiltersObj(filters) {
const filtersObj = filters.filters.reduce((acc, current) => {
const filterName = current.name.replace(/ /g, '_').toLocaleLowerCase();
if (!acc.hasOwnProperty(filterName)) {
acc[filterName] = [];
}
acc[filterName] = [].concat(current.keywords.map(item => item.toLocaleLowerCase()));
return acc;
}, {});
return filtersObj;
}
函数filterTimelineData(filterObj,timelineData){
如果(!timelineData | |!filtersObj)返回[];
//创建一个以过滤器“name”为键的新对象;
const filters=Object.keys(filtersObj);
const filteredTimelineData=Object.keys(filtersObj).reduce((o,key)=>({…o,[key]:[]),{});
const filteredData=timelineData.events.reduce((acc,current)=>{
让filterMatch=false;
让filterMatchName='';
for(设i=0;i{
返回filtersObj[filters[i]].includes(item.toLocaleLowerCase());
});
if(filterMatch&&filterMatchName!==filters[i]){//,以避免在同一筛选器下使用不同类别的重复项
filterMatchName=过滤器[i];
acc[过滤器[i]]推送(当前);
}
}
返回acc;
},filteredTimelineData);
返回过滤器数据;
}
导出函数timelineFiltersObj(过滤器){
常量过滤器OBJ=过滤器。过滤器。减少((acc,电流)=>{
const filterName=current.name.replace(//g,'.').toLocaleLowerCase();
如果(!acc.hasOwnProperty(filterName)){
acc[过滤器名称]=[];
}
acc[filterName]=[].concat(current.keywords.map(item=>item.tolocalLowercase());
返回acc;
}, {});
返回过滤器OBJ;
}
期望输出:
- 有没有更简单的方法来解决这个问题
- 我将“filteredTimelineData”对象作为初始值传递给.reduce函数。这合法吗?我在网上找不到这个问题的具体答案
- 从时间复杂性的角度来看。如果数据集增长,此代码是否会导致内存问题
- 这是获得上述结果的简单方法。我在这个解决方案中使用了
JavaScript ES5
功能,除了IE9之外,几乎所有浏览器都支持它
const过滤器={
“过滤器”:[
{
“关键词”:[
“大西洋”,
“新不伦瑞克”,
“纽芬兰和拉布拉多”,
“爱德华王子岛”,
“新斯科舍省”
],
“名称”:“大西洋”
},
{
“关键词”:[
“安大略省”,
“魁北克”
],
“名称”:“加拿大中部”
},
{
“关键词”:[
“马尼托巴”,
“萨斯喀彻温省”,
“阿尔伯塔省”
],
“名称”:“草原省份”
},
{
“关键词”:[
“不列颠哥伦比亚省”
],
“名称”:“西海岸”
},
{
“关键词”:[
“努纳武特”,
“西北地区”,
“育空地区”
],
“名称”:“北”
},
{
“关键词”:[
“国家”
],
“姓名”:“国家”
}
]
};
常数时间线数据={
“事件”:[
{
“文本”:{
“标题”:“标题示例”,
“文本”:“事件描述”
},
“媒体”:{
“url”:”
},
“类别”:[
“新不伦瑞克”
]
},
{
“文本”:{
“标题”:“标题示例”,
“文本”:“事件描述”
},
“媒体”:{
“url”:”
},
“类别”:[
“国家”
]
},
{
“文本”:{
“标题”:“标题示例”,
“文本”:“事件描述”
},
“媒体”:{
“url”:”https://youtu.be/poOO4GN3TN4"
},
“类别”:[
“西北地区”
]
},
{
“文本”:{
“标题”:“标题示例”,
“文本”:“事件描述”
},
“媒体”:{
“url”:”
},
“类别”:[
“安大略省”
]
},
{
“文本”:{
“标题”:“标题示例”,
“文本”:“事件描述”
},
“媒体”:{
“url”:”
},
“类别”:[
“国家”
]
},
{
“文本”:{
“标题”:“标题示例”,
“文本”:“事件描述”
},
“媒体”:{
“url”:”https://philanthropy.cdn.redcross.ca/timeline/July2020-3.jpg"
},
“类别”:[
“不列颠哥伦比亚省”
]
},
{
“文本”:{
“标题”:“标题示例”,
“文本”:“事件描述”
},
“媒体