多重数据过滤

问题描述 投票:0回答:2

[请帮助我进行正确的多重过滤,应该可以按城市,标签和距离进行过滤,并且每个类别都有很多项目,例如:

城市:莫斯科,圣彼得堡,基辅,华沙,伦敦

标签:马拉松,半程马拉松,接力

距离:7km,22km,100km,42km

您可以标记任意数量的项目进行过滤

var events = [
{id: 0, date:"22.12.2019", name:"event1", city:"Moscow", distances:"100km", tags:[{id: 0, name: Marathon},{id: 1, name: Half Marathon}]},
{id: 1, date:"22.12.2019", name:"event2", city:"London", distances:"22km", tags:[{id: 0, name: Relay}]},
{id: 2, date:"22.12.2019", name:"event3", city:"Moscow", distances:"42km", tags:[{id: 0, name: Marathon},{id: 1, name: Relay}]},
{id: 3, date:"22.12.2019", name:"event4", city:"Kiev", distances:"100km", tags:[{id: 0, name: Marathon},{id: 1, name: Half Marathon},{id: 2, name: Эстафета}]},
{id: 4, date:"22.12.2019", name:"event5", city:"Warsaw", distances:"42km", tags:[{id: 0, name: Marathon}]},
{id: 5, date:"22.12.2019", name:"event6", city:"St. Petersburg", distances:"22km", tags:[{id: 0, name: Relay},{id: 1, name: Half Marathon}]},
{id: 6, date:"22.12.2019", name:"event7", city:"St. Petersburg", distances:"7km", tags:[{id: 0, name: Half Marathon}]},
]

例如,如果我选择了Marathon,Relay,42km,100km作为过滤条件,那么最好的过滤方法是,可以选择其他选项我尝试的方法:在过滤器类别下创建了3个数组,当我单击项目时,将其写到所需的数组中,然后像这样运行它:

const { filterCity } = this.state; // array of selected filters by city
    const { eventById } = this.props.Events.eventsList.events; // all events
    const allEvents = (eventById === null ? [] : eventById); //data check 
    const filtered = allEvents.filter((events) => {
      // eslint-disable-next-line no-plusplus
      for (let i = 0; i < filterCity.length; i++) {
        // eslint-disable-next-line no-plusplus
        for (let j = 0; j < events.tags.length; j++) {
          if (filterCity.indexOf(events.tags[j].name) !== -1) {
            return false;
          }
        }
      }
      return true;
    });

到目前为止,仅用于过滤城市,但是在这里您可以选择想要的城市以不同的顺序,并且会有规范,但是我做对了,因为我想立即将此功能添加到其他类别中,以便检查所有内容,结果可能会产生更多内部循环,也许有可能做得更好,或者请告诉我相关规范,请

P.S。我只在js上使用react任务

javascript reactjs filter
2个回答
1
投票

也许您可以执行类似的操作,在此将过滤器作为具有单个键/值对的对象数组进行传递。然后,您可以单独过滤这些过滤器,如果至少有一个过滤器匹配,则返回事件。

这应该允许您对多个过滤器类别以及这些类别中的多个值进行过滤。

const filters = [{ city: 'Moscow' }, { city: 'Kiev' }, { distances: '42km'} ];

events.filter(event => {

    // will return true if one of the filtered values is present in the event object
    return filters.some(filter => {
        return hasFilteredProperty(event, filter);
    });

});

// Pass filter as { key: value }
const hasFilteredProperty = (event, filterObj) => {

    const filterKey = Object.keys(filterObj)[0];

    if (filterKey === 'tags') {
        return hasFilteredTags(event, filterObj[filterKey]);
    } else {
        return event[filterKey] === filterObj[filterKey];
    }

}

// Pass filtered tags as an array of names: [ 'Half Marathon', 'Marathon', '100km' ]
const hasFilteredTags = (event, filteredTags) => {

    const eventTagNames = event.tags.map(tag => tag.name);
    return eventTagNames.some(tagName => filteredTags.includes(tagName));

}

0
投票

您可以使用数组includes函数检查filterCity中是否存在事件城市。对于其他类似的属性,您可以执行相同操作。对于标签,因为事件属性本身是一个对象数组,您可以首先使用map创建标签名称数组,然后检查filterTag中的至少一个元素是否存在。演示代码可以在下面看到。

let filterCity = ['Moscow', 'Russia']
let filterTag = ['Half Marathon', 'Relay']
let filteredEvent = events.filter(event => {
  if(filterCity.length && !filterCity.includes(event.city)) return false
   if(filterTag.length && !event.tags.map(tag => tag.name).find(tag => filterTag.indexOf(tag)>-1)) return false
 return true
})
© www.soinside.com 2019 - 2024. All rights reserved.