immutable.js过滤和mutate(删除)找到的条目

时间:2016-11-22 17:44:46

标签: javascript optimization logic immutable.js

我有两个循环,一个是每月的一天,另一个是本月的所有活动。假设我有10万个事件。 我正在寻找一种方法,以便在主要事件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的方式变得越来越小..

2 个答案:

答案 0 :(得分:4)

您可以尝试将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)

答案 1 :(得分:1)

通过重新启动已经处理过的元素,您不会更快地做任何事情。所有过滤器操作的成本平均会减半,但是在每次迭代中构建新列表都会花费你一些cpu周期,因此它不会明显更快(在大的意义上)。相反,您可以基于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>
&#13;
&#13;
&#13;