I have an array of objects that a user can perform search on. I’m using a ko.computed function based on the search to create another array of matched items for display.
self.matchedRecords = ko.computed(function() {
return ko.utils.arrayFilter(self.transponders(), function(r) {
return r.title.toLowerCase().indexOf($('.search-input').val().toLowerCase()) > -1
}
};
This works great and I’m really impressed with the performance so far.
This issue is I also need the “unmatched” records because I have to perform an addition operation on them in some cases (60% of the time). I don’t really want to create a second ko.computed function because then I have to run through this array a second time every time a search is performed.
So, my question: Is there a way that I can use the same ko.computed to create a second array of unmatched items? Basically run through the array and put each item in the matched or unmatched array…
If not, is it faster to:
1) create a second ko.computed to get the unmatched items from my array as the user searches; or
2) write an arrayDiff function and determine the unmatched items on demand if I need them.
Cheers!
If you are worried about performance, you could have a non-observable array that you populate while you iterate the search results in your computed. Also note that you are repeatedly selecting using jQuery inside your loop, which I think negates any KO-caused slowdowns.
I used
_.eachfrom Underscore to keep the code shorter. The drawback of this approach is that changes tomissedRecordscan’t (reliably) be bound to the UI (e.g. in case you have aforeachbinding).If you do need the
missedRecordsarray to be observable, and still want to keep things fast(er), you could do something like this:You could also skip
computedaltogether and just subscribe to changes to change the state of your arrays. For example: