Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Wishing For A Lazier Underscore

DZone's Guide to

Wishing For A Lazier Underscore

· Java Zone
Free Resource

Bitbucket is for the code that takes us to Mars, decodes the human genome, or drives your next car. What will your code do? Get started with Bitbucket today, it's free.

Sometimes the day of a developer gets awfully complicated. One of my less favorite moments are those when you have used a library for most of your project and then you realize you need things from it it was not designed to do. I was in this particular position last week, trying to stretch UnderscoreJS in ways it just wasn’t designed to bend.

Don’t get me wrong, I love UnderscoreJS, it brings the sweetness of C#’s LINQ-style chained queries to JavaScript arrays. If it was a person, I would totally hug it. But it made me smash my head against the wall a couple times when I realized that it lacks lazy evaluation of chained queries.

Why would I need that, you ask? Because sometimes I have to accomplish the darnest requirements. The original culprit was Kendo UI, an awesome UI-widget library by the guys at Telerik. The issue is that I had to completely override its built-in filtering mechanism since I needed it to be able to filter a data source in a master-detail fashion. For example, I have an array of customers, each customer has a sub-array of products it has bought. The grid displays a master row per-customer and detail rows for the products it has bought. Even so, the user should be able to filter by product, so if any customer had bought a particular product, it should be listed in the grid.

As long as I (and Google) know, this cannot be done out-of-the-box with Kendo UI unless you do it manually on server-side, since it can filter over all of the object properties, but not sub-arrays.

After some work, I managed to override the default filters and the original filter method in the grid’s data source. However, I needed a fast way to filter the data source like the original filtering mechanism did, so I recurred to UnderscoreJS. Performance was not that good; after wrapping the data source in an UnderscoreJS chain, I had to apply the filter method once per filter applied on the grid. The more filters, the worst performance got.

I eventually figured out that every time I was calling the filter function, it was iterating once over the entire data source. Of course performance was bad. Really dumb of me, since I was used to how LINQ worked; it allowed me to build a query in a fluent fashion and then execute it over the data source so it was iterated over just once. This process is called lazy evaluation of a query over a data source. UnderscoreJS does NOT feature lazy evaluation.

var filteredCustomers = 
    _(this.customers)
        .filter(function (customer) { // Iterates the array once...
            return customer.firstName === 'Luis';
        })
        .filter(function (customer) { // And then again...
            return customer.lastName === 'Aguilar';
        })
        .filter(function (customer) { // And again...
            return _(customer.products).any(function (product) { // LOL don't even ask...
                return product.name === 'Time Machine X9000-S'
            });
        });

I think the only thing left to do is to use another library to support my custom filtering mechanism. Sigh. I’ll let you know of my findings…

Bitbucket is the Git solution for professional teams who code with a purpose, not just as a hobby. Get started today, it's free.

Topics:

Published at DZone with permission of Luis Aguilar, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}