2016-11-22 17 views
8

Tôi có hai vòng, một cho mỗi ngày trong tháng, khác với tất cả các sự kiện trong tháng này. Giả sử tôi có 100 000 sự kiện. Tôi đang tìm cách xóa sự kiện khỏi các sự kiện chính List khi chúng đã bị "tiêu thụ".bộ lọc và biến thể immutable.js (loại bỏ) tìm thấy các mục

Mã này là một cái gì đó như:

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

Với lodash Tôi chỉ có thể làm một cái gì đó như:

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

Làm thế nào để thực hiện như nhau tối ưu hóa với immutablejs? Tôi không thực sự mong đợi một giải pháp cho cách của tôi để lặp lại danh sách, nhưng đối với một cách thông minh của việc giảm các sự kiện List theo cách nó nhỏ hơn và nhỏ hơn ..

Trả lời

4

Bạn có thể thử Map với sự kiện được chia thành thùng - dựa trên ví dụ của bạn, bạn bin dựa trên ngày - bạn có thể tra cứu một thùng, xử lý nó như một lô và loại bỏ nó O (1). Bản đồ không thể thay đổi là khá rẻ tiền, và giá vé tốt hơn nhiều so với lặp qua danh sách. Bạn có thể phải chịu chi phí của một lần binning, nhưng khấu hao nó trên O (1) tra cứu.

Something như thế này có lẽ:

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) 
+0

Btw, tôi nên thêm, phương pháp này là tinh khiết chức năng với không tác dụng phụ và sử dụng đệ quy đuôi. Nếu bạn muốn, nói phần còn lại của các mục, bạn có thể chỉ cần trả về một giá trị từ 'iter'. – Asti

1

By remobing đã được xử lý yếu tố bạn sẽ không làm bất cứ điều gì nhanh hơn. Chi phí của tất cả các hoạt động lọc sẽ được giảm một nửa về trung bình, nhưng việc xây dựng danh sách mới trong mỗi lần lặp sẽ khiến bạn mất một số chu kỳ CPU để nó không nhanh hơn đáng kể (theo nghĩa lớn). Thay vào đó, bạn có thể xây dựng một chỉ mục, ví dụ như một bản đồ bất biến, dựa trên các initialDate -s, làm cho tất cả các cuộc gọi filter không cần thiết.

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>

Các vấn đề liên quan