【问题标题】:immutable.js filter and mutate (remove) found entriesimmutable.js 过滤和变异(删除)找到的条目
【发布时间】:2017-04-06 12:18:15
【问题描述】:

我有两个循环,一个用于一个月中的每一天,另一个用于本月的所有事件。假设我有 100 000 个事件。 我正在寻找一种方法从主要事件List 中删除事件,一旦它们被“消耗”。

代码是这样的:

const calendarRange = [{initialDate}, {initialDate}, {initialDate}, {initialDate}, ...] // say we have 30 dates, one for each day
const events = fromJS([{initialDate}, {initialDate}, {initialDate}, ...]) // let's say we have 100 000
calendarRange.map((day) => {
  const dayEvents = events.filter((event) => day.get('initialDate').isSame(event.get('initialDate'), 'day')) // we get all events for each day 
  doSomeThingWithDays(dayEvents)
  // how could I subtract `dayEvents` from `events` in a way
  // the next celandarRange iteration we have less events to filter? 
  // the order of the first loop must be preserved (because it's from day 1 to day 3{01}])
}

使用 lodash 我可以做类似的事情:

calendarRange.map((day) => {
  const dayEvents = events.filter((event) => day.get('initialDate').isSame(event.get('initialDate'), 'day')) // we get all events for each day 
  doSomeThingWithDays(dayEvents)
  pullAllWith(events, dayEvents, (a, b) => a === b)
}

如何用 immutablejs 完成同样的优化?我并不是真的期待我的迭代列表方式的解决方案,而是一种智能的方式来减少事件List,使其变得越来越小..

【问题讨论】:

    标签: javascript optimization logic immutable.js


    【解决方案1】:

    您可以尝试Map 将事件拆分为垃圾箱-根据您的示例,您可以根据日期进行垃圾箱-您可以查找垃圾箱,将其作为批处理并将其删除 O(1)。不可变映射相当便宜,而且比遍历列表要好得多。您可能会产生一次性分箱的成本,但可以通过 O(1) 查找来分期付款。

    可能是这样的:

    eventbins = OrderedMap(events.groupBy(evt => evt.get('initialDate').dayOfYear() /* or whatever selector */)) 
    
    function iter(list, bins) { 
     if(list.isEmpty()) 
       return
     day = list.first()
     dayEvents = bins.get(day.dayOfYear())
     doSomeThingWithDays(dayEvents)
     iter(list.shift(), bins.delete(day))
    }
    
    iter(rangeOfDays, eventbins)
    

    【讨论】:

    • 顺便说一句,我应该补充一点,该方法是纯函数式的,具有零副作用并使用尾递归。如果你想,说其余的项目,你可以简单地从iter返回一个值。
    【解决方案2】:

    通过移除已经处理过的元素,你不会让任何事情变得更快。所有过滤器操作的成本平均会减半,但是在每次迭代中构建新列表会花费你一些 cpu 周期,因此它不会显着加快(在大 O 意义上)。相反,您可以基于 initialDate-s 构建索引,例如不可变映射,从而使所有 filter 调用变得不必要。

    const calendarRange = Immutable.Range(0, 10, 2).map(i => Immutable.fromJS({initialDate: i}));
    
    const events = Immutable.Range(0, 20).map(i => Immutable.fromJS({initialDate: i%10, i:i}));
    
    
    const index = events.groupBy(event => event.get('initialDate'));
    
    calendarRange.forEach(day => {
      const dayEvents = index.get(day.get('initialDate'));
      doSomeThingWithDays(dayEvents);
    });
    
    function doSomeThingWithDays(data) {
      console.log(data);
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.1/immutable.js"></script>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-22
      • 1970-01-01
      • 2021-11-09
      • 2014-07-08
      • 1970-01-01
      • 2021-02-15
      • 1970-01-01
      相关资源
      最近更新 更多