99

I'm looking for a JavaScript library that will allow me to query complex JSON objects using a LINQ-like syntax. A quick search found a couple of promising options that look they might offer what I need:

LINQ to JavaScript and jLinq

  • Does any one have any experience using them?
  • What are some pros and cons?
  • Is the performance comparable?
  • Does the function-passing syntax of LINQ to JavaScript offer any hidden benefits (I personally find the syntax of jLinq more appealing on first glance)?
  • What have you found lacking in either project?
  • Did you ever try contacting the authors? How responsive were they?
  • What project is more widely used?

I think it will be the first one to get a thorough try-out.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Tom Tresansky
  • 19,364
  • 17
  • 93
  • 129
  • 1
    I just released jinqJs.com open source project, that should help you. – NYTom Mar 29 '15 at 16:04
  • Try LINQ 4 ES 2015, http://fermium-co.github.io/LINQ4ES2015/ All LINQ methods with same C# syntax. Implemented the same .NET LINQ to object specifications. – Yaser Moradi Aug 24 '15 at 18:51
  • I released dinqyjs.com a couple of years ago, has a Linq-like syntax and lots of functionality. – garryp Feb 17 '17 at 16:36
  • 2
    This question is old and rightly closed, but for readers who happen across it, the main features of LINQ (filtering, transforming, and aggregating) can be performed using the built in [`filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter), [`map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map), and [`reduce`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce) array functions. The new lambda syntax helps make the code look much more similar to LINQ code. – jpmc26 Jan 10 '18 at 19:57
  • Few months ago I released `Linq-Collections` (https://www.npmjs.com/package/linq-collections). It uses deferred executions and tons of internal optimizations to be blazing fast. Based on Microsoft's standard (if you know C# Linq then you know linq-collections) – Ivan Sanz Carasa Feb 02 '18 at 14:47
  • I just wrote a LINQ library for Javascript: https://siderite.dev/blog/linq-in-javascript-linqer/ I am currently reviewing what other people have done. – Siderite Zackwehdex Jan 06 '20 at 16:30

10 Answers10

72

You might want to check out linq.js. It follows the .NET lambda syntax and looks to be well integrated in a Microsoft environment.

LINQ for JavaScript - http://linqjs.codeplex.com/

Pros

  • Implements all .NET 4.0 methods
  • Complete lazy evaluation
  • Full IntelliSense support for VisualStudio
  • Supports jQuery
  • Supports Windows Script Host
  • Binding for Reactive Extensions for JavaScript(RxJS) and IntelliSense Generator
  • NuGet install support
  • Updated recently (last release Jan 2011)
  • Syntax conforms to lambda syntax in C#

Cons

  • The linq.js library is a little large.
  • If you are already using jQuery or other js library, the most commonly used functionality is probably already available. See especially jQuery's filter, and 'Any' methods.
RMalke
  • 4,048
  • 29
  • 42
Nathan Palmer
  • 1,970
  • 1
  • 20
  • 28
39

The most basic and frequently used Linq operators are very commonly defined in widely used JS libraries. They just have different names (in fact, they have more traditional names than in Linq). Select becomes map, Where becomes filter, First and FirstOrDefault become [0].

Almost no library I know of (including I think the ones you linked to) bother to make the implementation lazy as in .NET Linq, they just evaluate immediately using arrays.

For a very nice, complete set of functional list operations, try: http://osteele.com/sources/javascript/functional/

Daniel Earwicker
  • 114,894
  • 38
  • 205
  • 284
  • Being familiar with LINQ, keeping as much of the syntax the same would be a huge help. The lazy loading is not a concern. This seems like it does have all the functionality I need, but I'll have to experiment some. I'm keeping the question open for now, in the hope someone WILL stumble by who has used the JavaScript LINQ libraries and share their experiences. After some time goes by, if nobody else does, I'll be sure to give you the answer. – Tom Tresansky Mar 22 '10 at 23:03
  • 26
    @Tom - I tend to be a bit wary of libraries that attempt to simulate the experience of using language X inside language Y if there is already a good way of doing the same thing in language Y. I think it's better to learn the "idioms" of language Y. People were writing functional sequence operators in JS before Linq came out, and in JS they kept the "traditional" Lispy names and approaches, so that's now the more JS style. So I say "When in Rome..." Even to the extent of how I lay out curly braces, which line up vertically in C#, but in JS and Java I put the first one on the same line, etc. – Daniel Earwicker Mar 23 '10 at 08:28
  • 2
    Very useful answer - especially that 'select' maps to 'map'. In that case, underscore.js could be used as well – PandaWood Sep 15 '11 at 00:57
  • 1
    What about joining two arrays? I was trying to figure out how to get the elements of array A that are not in array B, but there doesn't seem to be a way to do that in JQuery. It's quite trivial in LINQ. – Zephyr was a Friend of Mine Nov 07 '11 at 11:06
  • @Noel Abrahams - for this kind of thing why not use the ES5 Array methods instead of jQuery? e.g. `a1.filter(function(e) { return a2.indexOf(e) == -1; })` – Daniel Earwicker Nov 08 '11 at 17:00
  • @Daniel, it's not quite as neat as writing .Except(a2). I agree with your philosophy in principle. I just feel that linq _can_ be thought of as a language-neutral library for manipulating arrays. – Zephyr was a Friend of Mine Nov 09 '11 at 10:24
  • For `FirstOrDefault`, a good match is [Array.prototype.find()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find): *"The find() method returns the value of the first element in the provided array that satisfies the provided testing function."* – DavidRR Mar 11 '20 at 11:13
14

Have you seen Rx for Javascript, yet? That's what you want.

Richard Anthony Hein
  • 10,550
  • 3
  • 42
  • 62
  • 1
    Thanks for the link, I hadn't seen this, and after viewing the project pages and videos for this and Rx I can already see where this could be handy. However, it is not what I'm looking for. I want to perform LINQ-like queries on JSON objects that have many levels of nesting. – Tom Tresansky Mar 22 '10 at 22:50
  • Yeah, you can do that with Rx - it's for querying any data or object in a reactive/asynch (i.e. AJAX-style) way, see an example of grabbing JSON data and then querying it using the Rx library here: http://codebetter.com/blogs/matthew.podwysocki/archive/2010/03/17/the-reactive-extensions-for-javascript-released.aspx – Richard Anthony Hein Mar 23 '10 at 05:07
  • 2
    I was going to suggest this but it's not really the same as linq to objects. (If it was, why would we need both Rx and Linq to Objects in .NET?) It works in the opposite direction to normal Linq in terms of the flow of data. – Daniel Earwicker Mar 23 '10 at 08:24
  • Everything you can do with a pull (IEnumerable) collection (including a single item in a collection) you can do with a push interface too (IObservable). That means LINQ queries. You just think in terms of events or pushed data, but you still query it the same way. For Javascript I imagine they thought System.Reactive was a higher priority in an AJAJ/AJAX world, maybe System.Interactive is coming later. You can do anything with Rx that you'd do with Linq to Objects you just work with data (or computations) being pushed to you instead of you pulling them. – Richard Anthony Hein Mar 23 '10 at 14:47
  • 1
    @RichardHein your prophecy came true, System.Interactive for JS is now there in the form of Ix.JS @ http://rx.codeplex.com/SourceControl/changeset/view/ef6a42709f49#Ix.JS%2fixjs.js – Chris DaMour Nov 16 '12 at 01:12
  • 27
    I hate that this is the accepted answer. Yeah, sure, it's academically interesting that observables in .NET are similar to enumerables, but so what? Almost nobody who finds this question actually wants RX/observables (there are already much more useful implementations of that in knockout, angularjs, etc.) and the answer itself doesn't even try to explain what the relevance is, and even if it was really the most appropriate choice, it's hardly "leading" - it has about 1/5 the downloads of linq.js. – Aaronaught Jul 13 '13 at 16:09
  • 2
    @Aaronaught The answer was given over 3 years ago, and things have definitely changed, and linq.js is now way ahead of what it was back then. At the time, I believed rx.js was the best bet for doing LINQ operations with JS, as the other libraries were not great or incomplete and RX had fulltime developers working on it. Also, async was important and still is, IMO, in JavaScript - which is what you get with Observables. Finally, note Observables in Rx are very different from Knockout and AngularJS Observables, and serve different purposes. Your opinions are noted, and you're free to vote! :) – Richard Anthony Hein Jul 15 '13 at 15:15
  • 2
    @Aaronaught One more note ... if someone is looking for LINQ related libraries for JavaScript, then they should definitely know about Rx, as it's 100% LINQ, and knowing LINQ but not Rx is really only knowing half the story. Cheers. – Richard Anthony Hein Jul 15 '13 at 15:19
  • 2
    Having had extensive experience with RX, Linq, and JavaScript, I can say without hesitation that someone looking for Linq-like libraries for JavaScript definitely does *not* need to know about RX, and it's only half the story if you specifically define "the story" to be half RX. Claiming otherwise is muddying the waters and making it more difficult for people with simple requirements to understand their options. It's like telling someone who's looking for a bicycle that they need to learn about motorcycles first; sure, the relationship is interesting, but not particularly useful in context. – Aaronaught Jul 16 '13 at 00:21
  • 1
    @Aaronaught Give me one example of some LINQ operation you can do with any other library that you favor, that you cannot do with Rx. While the other libraries allow for synchronous, "pull-based" computations, Rx allows for asynch, "push-based", hence the "half the story" that everyone should know. Any asynch operation in Rx can work in a synchronous fashion, but the reverse is not true. Therefore, I stand by my answer that Rx allows you far more power and expressiveness for LINQ based computations than any other "LINQ-like" library. "Simple requirements" or not, Rx can do it all. – Richard Anthony Hein Jul 16 '13 at 14:11
  • @Aaronaught On a positive note, linq.js has some nice Rx bindings. http://linqjs.codeplex.com/documentation?referringTitle=Home – Richard Anthony Hein Jul 16 '13 at 14:16
  • Of course, we can do it with Rx, but Rx is mostly to model time domain. – Wickramaranga Feb 12 '17 at 03:36
  • @Aaronaught I'm don't think your comments aged well, LMAO :-D https://www.reactiveui.net/ https://platform.uno/ Took long enough to get to this point ... take a moment to appreciate that fact and enjoy. – Richard Anthony Hein Mar 30 '21 at 17:25
  • 1
    @Wickramaranga I think you missed the capabilities of Rx back then - see reactiveui.net and platform.uno now, and tell me that modelling the time domain shouldn't be the foundation of the entire design? – Richard Anthony Hein Mar 30 '21 at 17:27
  • 1
    @DoctorFoo truly. Been using Rx for some years now. Incredibly helpful to model data flow. Simplifies logic otherwise could've been nightmares. – Wickramaranga Mar 31 '21 at 06:03
11

I recommend taking a look at underscore.js. It is not a direct LINQ port like some of the others, but is a very comfortable "LINQ-like" experience. It supports all the filter, sort and project options that I need and has excellent documentation and community support.

As a bonus for Knockout users, there is UnderscoreKO that adds Underscore's array methods to Knockout's observable arrays. Demo

Matthew Nichols
  • 4,866
  • 4
  • 41
  • 48
  • 3
    I would definitively suggest underscore too. Unfortunately all of the available libraries lacks regarding performance. Being a c# developer myself, I would love to have c# syntax with a javascript oriented library but there is not any such available. All of the aforementioned libraries are "javascript wrappers' which means they try to implement LINQ functions the c# way. For example, looking at linq.js they have a Dictionary which, for the getter does a linear search. Javascript's object IS A DICTIONARY with superior performance but instead they implemented GetHashCodes etc. – George Mavritsakis Oct 26 '13 at 17:41
  • 4
    The distinctive feature of LINQ is lazy evaluation. Underscore.js does not have this functionality. However, there is [lodash](http://lodash.com) which is a superset of underscore, performs better, and supports lazy evaluation on chained methods: var arr = _.range(1000); _(arr).map(function (v) { return v + 1; }).filter(function (v) { return v % 2; }).take(100).value(); – srgstm Jun 09 '15 at 13:57
  • 3
    Yes...this was written a while ago; I would likely recommend lodash now also. I have been considering forking UnderscoreKO to allow lodash. But I am not sure I agree that lazy evaluation is "The" distinctive feature of LINQ. Mostly my appreciation of LINQ is that it typically communicates intent better than the alternative ways of doing things. Just a thought. At any rate both good libraries. – Matthew Nichols Jun 10 '15 at 15:26
5

I personally find the LINQ/set operations Union, Intersect, Except and Distinct on enumerables in .NET. very useful. There is a jquery plugin called jQuery Array Utilities which provides these methods to be used on arrays.

Code examples:

$.distinct([1, 2, 2, 3])

returns [1,2,3]

$.union([1, 2, 2, 3], [2, 3, 4, 5, 5])

returns [1,2,3,4,5]

$.instersect([1, 2, 2, 3], [2, 3, 4, 5, 5])

returns [2,3]

$.except([1, 2, 2, 3], [3, 4, 5, 5])

returns [1, 2]

  • This package [jquery-array-utilities](https://libraries.io/bower/jquery-array-utilities) can also be installed using [bower](https://bower.io). I would like like to add a disclaimer that I originally made the plugin :) – Kristian Abrahamsen Nov 28 '16 at 21:26
4

$linq: http://jscriptlinq.codeplex.com/

var users = [{username: "asmith", domain: "north_america"},
    {username: "tmcfarland", domain: "europe"},
    {username: "cdeckard", domain: "nort_america"}];

var groups = [{user: "ASMITH", groupName: "base_users"},
    {user: "TMCFARLAND", groupName: "admins"},
    {user: "CDECKARD", groupName: "base_users"},
    {user: "CDECKARD", groupName: "testers"}];

var results = $linq(users).join(groups,
    function (x) { return x.username; },    // key for 'users'
    "x => x.user",                          // key for 'groups'
    function (outer, inner)                 // function to generate results
    { 
        return "user: " + outer.username + 
            ", domain: " + outer.domain +
            ", group: " + inner.groupName;
    },
    "(x, y) => x.toLowerCase() == y.toLowerCase()");    // compare keys case-insensitively
Janus Troelsen
  • 20,267
  • 14
  • 135
  • 196
3

There are some duplicating libraries out there that try to port LINQ to JavaScript with a similar syntax and method names. However, in the JS community, the library that is getting really popular and providing the same functionality is Underscore.js.

orad
  • 15,272
  • 23
  • 77
  • 113
3

I've tried out most of these -- and I really like $linq: http://jscriptlinq.codeplex.com/ the best. It simply works the way you would expect c# linq to work -- including the chain ability.

user302084
  • 176
  • 1
  • 7
2

I'm looking for something like this myself and came across...

http://www.hugoware.net/Projects/jLinq

This looks really great! Maybe I just don't understand the point of Rx and observables compared to setting event handlers through something like jQuery.

Jacob Thomason
  • 3,062
  • 2
  • 17
  • 21
1

I recently made a LINQ library for JavaScript. It implemented most LINQ functions provided by .NET and it is the fastest of all the LINQ libraries.

http://fromjs.codeplex.com/

suckgamony
  • 19
  • 2