为了账号安全,请及时绑定邮箱和手机立即绑定

多重数据过滤

多重数据过滤

HUH函数 2022-01-07 21:07:58
请帮我做正确的多重过滤,应该可以按城市、标签、距离过滤,而且每个类别都有很多项,例如:城市:莫斯科、圣彼得堡、基辅、华沙、伦敦标签: 马拉松, 半程马拉松, 接力距离:7公里、22公里、100公里、42公里您可以标记任意数量的项目以进行过滤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 进行过滤,那么最好的过滤方法是什么在项目上,我将其写到所需的数组中,然后像这样运行它: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;    });到目前为止,仅用于过滤城市,但是在这里您可以按不同的顺序选择您想要的城市并且会有规范,但是我做对了吗,因为我想立即将此功能添加到其他类别中,以便检查一切,事实证明还有几个内部循环,也许可以做得更好,或者请告诉我规范
查看完整描述

2 回答

?
白衣非少年

TA贡献1155条经验 获得超0个赞

也许您可以这样做,将过滤器作为具有单个键/值对的对象数组传递。然后,您可以单独过滤它们并在至少一个过滤器匹配时返回事件。


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


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));


}


查看完整回答
反对 回复 2022-01-07
?
函数式编程

TA贡献1807条经验 获得超9个赞

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


let filterCity = ['Moscow', 'Russia']

let filterTag = ['Relay','Marathon']

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)==undefined) return false

 return true

})


console.log(filteredEvent)


查看完整回答
反对 回复 2022-01-07
  • 2 回答
  • 0 关注
  • 117 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信