{"id":1684,"date":"2013-08-12T00:00:00","date_gmt":"2013-08-12T00:00:00","guid":{"rendered":"https:\/\/test.simple-talk.com\/uncategorized\/functionally-similar-comparing-underscore-js-to-linq\/"},"modified":"2021-05-17T18:34:55","modified_gmt":"2021-05-17T18:34:55","slug":"functionally-similar-comparing-underscore-js-to-linq","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/development\/dotnet-development\/functionally-similar-comparing-underscore-js-to-linq\/","title":{"rendered":"Functionally Similar &#8211; Comparing Underscore.js to LINQ"},"content":{"rendered":"<div id=\"pretty\">\n<h1>Comparing Underscore.js to LINQ<\/h1>\n<h2>Overview<\/h2>\n<p class=\"start\">When LINQ was added to C# in ASP.Net 3.0, it changed the way that we work with data collections. When working with server-side data in web-based applications, LINQ is an invaluable time saver. LINQ makes short work of iterative functions by means of a simple syntax that is easy to read and understand. <\/p>\n<p>Unfortunately, server-side data is no longer enough. Users now expect the sort of fast and fluid web pages that require client side processing.  To be able to work with data on the client-side, you need to be comfortable with writing JavaScript. If you don&#8217;t have a good understanding of JavaScript, the transition from writing server side C# to JavaScript can be challenging. <\/p>\n<p>If you are already familiar with LINQ with C#, then it would help to be able to use a similar syntax with client-side data access.  Underscore.js allows you to work in JavaScript with arrays and object-collections in a similar way to LINQ, but how similar?  Let&#8217;s look at this in a bit more detail.<\/p>\n<h2>About Underscore.js <\/h2>\n<p>Underscore is an open source functional programming utility library for JavaScript. Underscore provides many useful functions for working with arrays or collections of JavaScript objects, including filtering, sorting and querying.<\/p>\n<p>Using underscore is as simple as adding the JavaScript file to your project and referencing it on the page.  <\/p>\n<pre class=\"lang:c# theme:vs2012\">  &lt;!-- underscore --&gt;\n    &lt;script src=\"\/underscore-min.js\"&gt;&lt;\/script&gt;<\/pre>\n<p>You can get the library file via <a href=\"https:\/\/www.nuget.org\/packages\/underscore.js\/\">NuGet<\/a>, <a href=\"http:\/\/cdnjs.com\/\">CDN<\/a> or by downloading the file directly from the <a href=\"http:\/\/underscorejs.org\/\">home page<\/a>. <\/p>\n<h3>Usage<\/h3>\n<p>Underscore offers two different syntax styles, a functional syntax and an object-oriented syntax. If you were introduced to JavaScript by writing jQuery, then the object-oriented style might be a more comfortable choice because it follows a similar approach. The two are operationally equivalent, so picking which style to use is a matter of personal preference.<\/p>\n<pre class=\"lang:c# theme:vs2012\">\/\/Functional syntax\n_.all(articles, function(article) { return article.isRead });\n\n\/\/OOP Syntax\n_(articles).all(function(article) { return article.isRead });\n<\/pre>\n<p>LINQ also has several syntax choices with its declarative query and functional (a.k.a. method chaining) syntaxes, but LINQ&#8217;s declarative query syntax has no equivalent in Underscore whereas both of Underscores styles are more representative of the functional syntax found in LINQ.<\/p>\n<pre class=\"lang:c# theme:vs2012\">\/\/LINQ functional or method chaining syntax\n\/\/Similar to both Underscore styles\narticles.All(article =&gt; article.IsRead);\n<\/pre>\n<p>Underscore shares with LINQ an ability to iterate through a dataset and produce equivalent results but it is implemented in a very different way. While LINQ generally returns an <code>IEnumerable<\/code><code>&lt;T&gt;<\/code><code>,<\/code> Underscore will simply return the results as an array or array of objects. Because Underscore generally returns array values rather than an object it doesn&#8217;t provide method chaining by default, instead a special <code>chain<\/code> function must be called to wrap the results in a chainable API.<\/p>\n<p>Several Underscore functions are almost identical in operation to LINQ, such as  <code>Any<\/code> and, <code>All<\/code> and <code>SortBy<\/code> (<code>OrderBy<\/code>). While other functions like <code>Select<\/code> and <code>Where<\/code> aren&#8217;t used in the same way although they are in LINQ.<\/p>\n<p> Let&#8217;s take a look at each of these functions in both C# and JavaScript to see how both are implemented and compare the similarities between them.<\/p>\n<h3>Any<\/h3>\n<p><code>Any<\/code><code> <\/code>which also goes by the alias of <code>some <\/code>in Underscore, will determine if any element in a list passes a test specified by the iterator of the function. Both LINQ and Underscore return a Boolean value and the enumeration is stopped once the test becomes <code>true<\/code>. You can see in the example below how both <code>Any<\/code> functions are used, the similarities are very close in either environment.<\/p>\n<p>In the following example a list of articles is checked to see if the set contains any unread articles.<\/p>\n<h4>Underscore:<\/h4>\n<pre class=\"lang:c# theme:vs2012\">\/\/Syntax\n_.any(list, [iterator]) \/\/returns boolean\n_(list).any([iterator]) \/\/returns boolean\n_.some(list, [iterator]) \/\/returns boolean\n_(list).some([iterator]) \/\/returns boolean\n\n\/\/Example: Check to see if the user has unread articles\nfunction hasUnreadArticles(articles) {\n    return _(articles).any(function (article) { return article.isRead});\n}<\/pre>\n<h4>LINQ:<\/h4>\n<pre class=\"lang:c# theme:vs2012\">\/\/Syntax\npublic static bool Any&lt;TSource&gt;(this IEnumerable&lt;TSource&gt; source)\n\n\/\/Example: Check to see if the user has unread articles\npublic bool HasUnreadArticles(List&lt;Article&gt; articles)\n{\n     return articles.Any(article =&gt; !article.IsRead);\n}<\/pre>\n<h3>All<\/h3>\n<p><code>All<\/code><code>,<\/code><code> <\/code>which also goes by the alias of <code>every <\/code>in Underscore, will determine if all element in a list passes a test specified by the iterator of the function. <code>All<\/code> will short-circuit when the outcome has been determined in both LINQ and Underscore. <code>All<\/code> is the logical opposite of <code>Any<\/code>.<\/p>\n<p>In the following example, a list of articles is checked to see if all of the articles in the set have been read.<\/p>\n<h4>Underscore:<\/h4>\n<pre class=\"lang:c# theme:vs2012\">\/\/Syntax\n_.all(list, [iterator]) \/\/returns boolean\n_(list).all([iterator]) \/\/returns boolean\n_.every(list, [iterator]) \/\/returns boolean\n_(list).every( [iterator]) \/\/returns boolean\n\n\/\/Example: Check to see if the user has read all of the articles\nfunction hasReadAllArticles(articles) {\n    return _(articles).all(function(article) { return article.isRead});\n};<\/pre>\n<h4>LINQ:<\/h4>\n<pre class=\"lang:c# theme:vs2012\">\/\/Syntax\npublic static bool All&lt;TSource&gt;(this IEnumerable&lt;TSource&gt; source)\n\n\/\/Example: Check to see if the user has read all of the articles\nprivate bool HasReadAllArticles(List&lt;Article&gt; articles)\n{\n    return articles.All(article =&gt; article.IsRead);\n}<\/pre>\n<h3>Each<\/h3>\n<p>With Underscore, <code>ForEach<\/code><code> <\/code>loops can be simplified by using the <code>each<\/code> function. The <code>each<\/code> function will iterate through a list and perform an operation on each item in the set. There is no equivalent function in LINQ however there is a <code>ForEach<\/code> method that is part of the <code>List<\/code> object which operates much like its Underscore counterpart.<\/p>\n<p>In the following example each we use the <code>each<\/code> and <code>ForEach<\/code> functions to mark all of the articles in a collection as read.<\/p>\n<h4>Underscore:<\/h4>\n<pre class=\"lang:c# theme:vs2012\">\/\/Syntax\n\/\/_.each(list, iterator)\n\/\/_(list).each(iterator)\n\n\/\/Example: Mark all articles as read\nfunction markAllAsRead(articles) {\n    _(articles).each(function (article) { article.isRead = true; });\n    return articles;\n};\n<\/pre>\n<h4>List&lt;T&gt; (System.Collections.Generic)<\/h4>\n<pre class=\"lang:c# theme:vs2012\">\/\/Syntax\n\/\/public void ForEach(Action&lt;T&gt; action)\n\npublic void MarkAllAsRead(List&lt;Article&gt; articles)\n{\n    articles.ForEach(a =&gt; a.IsRead = true);\n}<\/pre>\n<h3>SortBy<\/h3>\n<p>You can sort lists of arrays or objects by using the <code>SortBy<\/code> function of Underscore. <code>SortBy<\/code> will return a copy of the list sorted in ascending order, so you will assign the return value of the function. <code>SortBy<\/code> can use an iterator, or property name of an object can be used by passing in the string name of an objects property. Although <code>SortBy<\/code> works similar to LINQs <code>OrderBy<\/code> method, there is no Underscore equivalent to get a reversed sort. Instead the results must be reversed using the JavaScript <code>reverse<\/code> function, whereas with LINQ you would use the <code>OrderByDecending<\/code> method.<\/p>\n<p>In the examples below, a list of articles is sorted by author name in both ascending and descending order.<\/p>\n<h4>Underscore:<\/h4>\n<pre class=\"lang:c# theme:vs2012\">\/\/Syntax\n_.sortBy(list, iterator [property name])\n_(list).sortBy(iterator [property name])\n\n\/\/sort a list of articles by the author property\nfunction sortArticlesByAuthors(articles) {\n    return _.sortBy(articles, \"author\");\n};\n\n\/\/sort a list of articles by the author property in decending order\nfunction sortArticlesByAuthors(articles) {\n    return _.sortBy(articles, \"author\").reverse();\n};\n<\/pre>\n<h4>LINQ:<\/h4>\n<pre class=\"lang:c# theme:vs2012\">\/\/Syntax\npublic static IOrderedEnumerable&lt;TSource&gt; OrderBy&lt;TSource, TKey&gt;(\n    this IEnumerable&lt;TSource&gt; source,\n    Func&lt;TSource, TKey&gt; keySelector\n)\n\n\/\/sort a list of articles by the author property\nprivate List&lt;Article&gt; SortArticlesByAuthor(List&lt;Article&gt; articles)\n{\n    return articles.OrderBy(article =&gt; article.Author).ToList();\n}\n\n\/\/sort a list of articles by the author property in decending order\nprivate List&lt;Article&gt; SortArticlesByAuthor(List&lt;Article&gt; articles)\n{\n    return articles.OrderByDecending(article =&gt; article.Author).ToList();\n}\n<\/pre>\n<h3>Select<\/h3>\n<p>The <code>select<\/code> function in Underscore is vastly different from the one in LINQ. The <code>S<\/code><code>elect<\/code> method in LINQ is used for projections, the operation of transforming an object into a new model that represents a subset of data for a specific use or view. Underscore&#8217;s <code>select<\/code><code>,<\/code> however, is a filtering or restriction operator that returns a restricted result set of objects to satisfy a specified condition. This is why <code>select<\/code> in Underscore also goes by the alias of <code>filter<\/code>, since the function returns a filtered result set.<\/p>\n<p>Because the <code>select<\/code> function of Underscore is a restriction operator, we will have to compare it to a similar restriction operator in LINQ. For this comparison, LINQ&#8217;s <code>Where<\/code> method is actually quite similar.<\/p>\n<p>In the example below, Underscore and LINQ are used to filter a list of objects. In this case we filter a list of articles that fall within a specified date range. It&#8217;s important to remember that the result set that is returned is of the same object structure that the function was initially given.<\/p>\n<h4>Underscore:<\/h4>\n<pre class=\"lang:c# theme:vs2012\">\/\/Syntax\n_.select(list, iterator)\n_.filter(list, iterator)\n_(list).select(iterator)\n_(list).filter(iterator)\n\n\n\/\/Returns articles within a given date range\nfunction getArticlesByDateRange(articles, beginDate, endDate) {\n    return _(articles).select(function (article) {\n        var articleDate = Date.parse(article.pubDate);\n        return articleDate &gt;= beginDate &amp;&amp; articleDate &lt;= endDate;\n    });\n};<\/pre>\n<h4>LINQ:<\/h4>\n<pre class=\"lang:c# theme:vs2012\">\/\/Syntax\npublic static IEnumerable&lt;TSource&gt; Where&lt;TSource&gt;(\n    this IEnumerable&lt;TSource&gt; source,\n    Func&lt;TSource, bool&gt; predicate\n)\n\n\/\/Returns articles within a given date range\nprivate List&lt;Article&gt; GetArticlesByDateRange(List&lt;Article&gt; articles, \nDateTime beginDate, DateTime endDate)\n{\n    return articles.Where(article =&gt; DateTime.Parse(article.PubDate) &gt;=\n          beginDate &amp;&amp; DateTime.Parse(article.PubDate) &lt;= endDate).ToList();\n}<\/pre>\n<h3>Where<\/h3>\n<p>Using the <code>where<\/code> function in Underscore is similar in some respects <code>Where<\/code> in LINQ. In both LINQ and Underscore, <code>where<\/code> is a restrictive operator that returns a filtered set of data. The <code>where<\/code> function in Underscore is limited to one or more exact key-value pair matches, although LINQ is able to test a value by virtually any criteria. If you need more than key-value pair matches then the select or filter function should be used instead.<\/p>\n<p>In the example below Underscore and LINQ are used to filter a set of data. In this case we filter a list of articles where the IsRead property has been set to false.<\/p>\n<h4>Underscore:<\/h4>\n<pre class=\"lang:c# theme:vs2012\">\/\/Syntax\n_(list).where(properties)\n_.where(list, properties)\n\n\/\/Returns unread articles\nfunction getUnreadArticles(articles) {\n    return _(articles).where({\"isRead\": false});\n};\n<\/pre>\n<h4>LINQ:<\/h4>\n<pre class=\"lang:c# theme:vs2012\">\/\/Syntax\npublic static IEnumerable&lt;TSource&gt; Where&lt;TSource&gt;(this \nIEnumerable&lt;TSource&gt; source,    Func&lt;TSource, bool&gt; predicate)\n\n\/\/Returns unread articles\nprivate List&lt;Article&gt; GetUnreadArticles(List&lt;Article&gt; articles)\n{\n    return articles.Where(article =&gt; article.IsRead == false).ToList();\n}<\/pre>\n<h3>Map<\/h3>\n<p>The map function in Underscore is used for projections and is comparable to LINQ&#8217;s Select method. The result of map is a new array of values mapped by the iterators function.<\/p>\n<p>In the following examples, map and Select are used to transform a set of larger article objects into a set of simplified article preview objects. The article preview contains the article&#8217;s title, author and description which is truncated to 160 characters (including the ellipsis). The transformation here is fairly simple, however we are not restricted to only simple operations and the iterator could be designed to do almost any operation.<\/p>\n<h4>Underscore:<\/h4>\n<pre class=\"lang:c# theme:vs2012\">\/\/Syntax\n_(list).map(iterator)\n_.map(list, iterator)\n\nfunction getArticlePreviews(articles) {\n    return _(articles).map(function (a) { \n        return { \n            'title': a.title, \n            'author': a.author, \n            'shortDescription': a.description.substring(0, 157) + \"...\"\n        }\n    })\n};<\/pre>\n<h4>LINQ:<\/h4>\n<pre class=\"lang:c# theme:vs2012\">\/\/Syntax\npublic static IEnumerable&lt;TResult&gt; Select&lt;TSource, TResult&gt;(\n    this IEnumerable&lt;TSource&gt; source,\n    Func&lt;TSource, TResult&gt; selector\n)\n\nprivate List&lt;ArticlePreview&gt; GetArticlePreviews(List&lt;Article&gt; articles)\n{\n    return articles.Select(article =&gt; new ArticlePreview()\n    {\n        Title = article.Title,\n        Author = article.Author,\n        SortDescription = article.Description.Length &gt; 157 ?\n          article.Description.Remove(157) + \"...\" : article.Description\n     }).ToList();\n}<\/pre>\n<h2>Chain<\/h2>\n<p>Underscore&#8217;s functions, unlike LINQ, do not use fluent method-chaining by default. This is because Underscore returns a collection of objects whereas LINQ methods return an <code>IEnumerable<\/code> object. To enable chaining in Underscore the <code>chain<\/code> function can be called. Beginning an operation with <code>chain<\/code> will cause the return value to be a wrapped object. When the chain is complete then the <code>value<\/code> method can be called to return the final result.<\/p>\n<p>Another significant difference between chaining in Underscore versus LINQ is how each method is executed. LINQ uses deferred execution, meaning that commands are stored in the result until, and not executed until, the result is iterated over in a <code>For Each<\/code> loop or <code>ToList<\/code> is called. When chaining in Underscore, every function call immediately executes and iterates through the data set returning a value. The value is then wrapped in an object to continue the chain.<\/p>\n<p>The following example uses chaining to create a view based on a collection of articles. To do this, we will chain the <code>where<\/code>, <code>map<\/code>, and <code>sortBy<\/code> functions together. First the list of articles is filtered for items that have not been read, and then a simplified projection is created. Finally, the items are sorted by author name and returned.<\/p>\n<h4>Underscore:<\/h4>\n<pre class=\"lang:c# theme:vs2012\">function getReadingList(articles) {\n    return _.chain(articles)\n        .where({ \"isRead\": false })\n        .map(function (a) {\n            return {\n                'title': a.title,\n                'author': a.author,\n                'shortDescription': a.description.substring(0, 157) + \"...\"\n            }\n        })\n        .sortBy(\"author\").value();\n};\n<\/pre>\n<h4>LINQ:<\/h4>\n<pre class=\"lang:c# theme:vs2012\">public List&lt;ArticlePreview&gt; GetReadingList(List&lt;Article&gt; articles)\n   {\n        return articles.Where(article =&gt; !article.IsRead)\n            .Select(article =&gt; new ArticlePreview()\n                {\n                    Title = article.Title,\n                    Author = article.Author,\n                    SortDescription = article.Description.Length &gt; 157 \n                      ? article.Description.Remove(157) + \"...\" : article.Description\n                })\n            .OrderBy(item =&gt; item.Author).ToList();\n    }<\/pre>\n<table>\n<tbody>\n<tr>\n<td>\n<p class=\"MsoNormal\"><strong>LINQ<\/strong><\/p>\n<\/td>\n<td>\n<p class=\"MsoNormal\"><strong>Underscore<\/strong><\/p>\n<\/td>\n<td>\n<p class=\"MsoNormal\"><strong>Operator Category<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p class=\"MsoNormal\">Any<\/p>\n<\/td>\n<td>\n<p class=\"MsoNormal\">any<\/p>\n<\/td>\n<td>\n<p class=\"MsoNormal\">Quantifier<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p class=\"MsoNormal\">All<\/p>\n<\/td>\n<td>\n<p class=\"MsoNormal\">all<\/p>\n<\/td>\n<td>\n<p class=\"MsoNormal\">Quantifier<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p class=\"MsoNormal\">Each (not LINQ)<\/p>\n<\/td>\n<td>\n<p class=\"MsoNormal\">forEach<\/p>\n<\/td>\n<td>\n<p class=\"MsoNormal\">Iterator<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p class=\"MsoNormal\">OrderBy<\/p>\n<\/td>\n<td>\n<p class=\"MsoNormal\">sortBy<\/p>\n<\/td>\n<td>\n<p class=\"MsoNormal\">Ordering<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p class=\"MsoNormal\">Where<\/p>\n<\/td>\n<td>\n<p class=\"MsoNormal\">where (when value is an exact match)<\/p>\n<\/td>\n<td>\n<p class=\"MsoNormal\">Restriction <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p class=\"MsoNormal\">Where<\/p>\n<\/td>\n<td>\n<p class=\"MsoNormal\">filter or select<\/p>\n<\/td>\n<td>\n<p class=\"MsoNormal\">Restriction<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p class=\"MsoNormal\">Select<\/p>\n<\/td>\n<td>\n<p class=\"MsoNormal\">map<\/p>\n<\/td>\n<td>\n<p class=\"MsoNormal\">Projection<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p class=\"MsoNormal\">&#8212;<\/p>\n<\/td>\n<td>\n<p class=\"MsoNormal\">chain | value<\/p>\n<\/td>\n<td>\n<p class=\"MsoNormal\">Utility<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p class=\"MsoNormal\">ToList<\/p>\n<\/td>\n<td>\n<p class=\"MsoNormal\">&#8212;<\/p>\n<\/td>\n<td>\n<p class=\"MsoNormal\">Conversion<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"caption\">A quick reference list for the functions reviewed in this article.<\/p>\n<h2>Conclusion<\/h2>\n<p>Underscore is a great utility for working with sets of data in JavaScript. There are a few cases when a function name from Underscore doesn&#8217;t perform the same task as it does in LINQ, but this is rare. It is important to be mindful of their different implementations with respect to chaining and deferred execution. Even though Underscore isn&#8217;t identical to LINQ, they are close enough in operation that the learning curve for Underscore is very minimal.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Underscore.JS is a useful JavaScript library for anyone familiar with the LINQ syntax. It is not a direct LINQ port like Rx or linq.js, but provides a very useful &#8220;LINQ-like&#8221; experience for anyone familiar with functional programming. Is it similar enough to LINQ to make it easy to transfer your existing skills?&hellip;<\/p>\n","protected":false},"author":58772,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143538],"tags":[4143,4157,4911,4706],"coauthors":[],"class_list":["post-1684","post","type-post","status-publish","format-standard","hentry","category-dotnet-development","tag-net","tag-asp-net","tag-javascript","tag-linq"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/1684","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/58772"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=1684"}],"version-history":[{"count":3,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/1684\/revisions"}],"predecessor-version":[{"id":40943,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/1684\/revisions\/40943"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=1684"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=1684"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=1684"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=1684"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}