Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

immutable.js filter and mutate (remove) found entries

I have two loops, one for each day of the month, other with all events for this month. Let's say I have 100 000 events. I'm looking for a way to remove events from the main events List once they were "consumed".

The code is something like:

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}])
}

With lodash I could just do something like:

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

How to accomplish the same optimization with immutablejs? I'm not really expecting a solution for my way of iterating the list, but for a smart way of reducing the events List in a way it get smaller and smaller..

like image 243
enapupe Avatar asked Nov 22 '16 17:11

enapupe


People also ask

Are JS filters immutable?

The filter method runs all of the array elements against a function that you provide and if they pass the criteria, it will create a new array and store that element. Because it does not modify the original array it is considered immutable.

How do I remove an item from an immutably array?

Get the array and the index. Form an ArrayList with the array elements. Remove the specified index element using remove() method. Form a new array of the ArrayList using mapToInt() and toArray() methods.

Is array slice immutable?

You can create an immutable copy of an array using Array. slice() with no arguments, or with the Array. from() method. It's considered a best practice to do so before manipulating an array.

What is immutable list in JavaScript?

An Immutable List is similar to a JavaScript array, but different enough to catch you out if you don't create a List correctly. Here are all the different ways to create a List, using arrays, objects, and everything else.


1 Answers

You can try a Map with events split into bins - based on your example, you bin based on dates - you can lookup a bin, process it as a batch and remove it O(1). Immutable maps are fairly inexpensive, and fare much better than iterating over lists. You can incur the cost of a one time binning, but amortize it over O(1) lookups.

Something like this perhaps:

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)
like image 185
Asti Avatar answered Oct 19 '22 05:10

Asti