2018-03-21

How to Implement LINQ methods in JavaScript - Part 4

blogentry, programming, quicktip, series

banner

Photo by Chris Lawton on Unsplash This is the 4th part of the series and I will cover common Set operations in this article.

Here are the methods covered so far.

  1. Part 1 〰️ Select, Aggregate, Where, OrderBy (Ascending, Descending)
  2. Part 2 〰️ Any, Distinct, Concat, SelectMany
  3. Part 3 〰️ Reverse, Zip, Min/Max
  4. Part 4 〰️ Union, Intersect, Except
  5. Part 5 〰️ Sum, Average, Count
  6. Part 6 〰️ First, Last, DefaultIfEmpty, Skip, Take
  7. Part 7 〰️ Empty, Repeat, Range
  8. Part 8 〰️ All, Contains, SequenceEqual

🔴 Overview

Here are the methods covered. [table id=4 /] There is no one-to-one equivalent in JavaScript, so I added Lodash equivalents in the table this time. For production codes, use Lodash as their implementation is thoroughly battle-tested.

The sample collections used in this part are shown as below. (Orders is same as last 3 series and I added DomesticOrders and InternationalOrders for examples this time)

C

https://gist.github.com/dance2die/970ab56eb3e4f8bafdbb8c7efd87ab66

JavaScript

https://gist.github.com/dance2die/df3097d46a30783bcd5948384137f4c8

🔴 Examples

🔸 Union

Union combines two sequences (of type IEnumerable<T>) into one without duplicates.

https://gist.github.com/dance2die/9bbfd498df8aff4386c2ef90eb9b476b

https://gist.github.com/dance2die/c314cca86619171bdd1f9c43f73ed4ff

Results

https://gist.github.com/dance2die/5c9fd4d6b744e1456c431474d4d8b0f5

I've extended the Array prototype to make the JavaScript version look similar to the LINQ version. 📝NOTE: "Union" in Lodash is named _.union.

🔸 Intersect

"Intersect" compares two sequences and return another sequence with a "common" value.

How do you check for the "commonness"? Intersect in LINQ provides an overload that lets you specify how to compare each value in two sequences by passing an object of type implementing IEqualityComparer<T> interface.

https://gist.github.com/dance2die/8391d61650a16a3c9c25800e305ac6e6

https://gist.github.com/dance2die/ace99d382339e96a75da8ac08dea8df9

Results

https://gist.github.com/dance2die/a6db6ac8f6a8976e180d1d905fb4a19e

Our contrived order array contains objects with a property called id so I passed a callback (idSelector) to let Array.prototype.intersect to use it to make a comparison for each value in two sequences.

📝NOTE: While Intersect in LINQ is similar to _.intersectionWith in Lodash, JavaScript version is roughly equivalent to _.intersectionBy.

🔸 Except (Difference)

"Except" compares two sequences and return a new sequence with values that exists in the caller but not in the compared.

https://gist.github.com/dance2die/00b325ab6c05f3fb40f4085720c177fb

https://gist.github.com/dance2die/ee35c21462154dfaa9881bf81934c5d1

Results

https://gist.github.com/dance2die/61816659a4be8fd961b86c2dfdccaf78

The implementation of Array.prototype.except is almost same as intersect.

The only difference between Array.prototype.intersect and Array.prototype.except is whether to include the record in the other set or not.

Take a close look at callback in filter method.

https://gist.github.com/dance2die/b0d97fd31fd6eb533e9e9b81812944f5

📝NOTE: While Except in LINQ is similar to _.differenceWith in Lodash, JavaScript version is roughly equivalent to _.differenceBy.

🔴 Closing Remark

"Union", "Intersect", and "Except" are the most common Set operations. I hope this article helped you understand how to implement Set operations in JavaScript.

JavaScript implementations in the examples above are not production ready as it's not optimized/tested. So as I mentioned before, use Lodash for Set operations in JavaScript.

Any feedback or error reports are always welcome.

The full source code and instructions on how to run them are on GitHub.