From 5c3c1aea549ed7666cfdc42cb2f2dce31ed6565a Mon Sep 17 00:00:00 2001 From: Mihai Ciuraru Date: Wed, 11 Mar 2020 17:37:03 +0200 Subject: [PATCH] Added compare function for orderBy and thenBy --- linq.d.ts | 6 +++++- linq.js | 37 +++++++++++++++++++++++-------------- package.json | 2 +- test/ordering.js | 18 +++++++++++++++++- 4 files changed, 46 insertions(+), 17 deletions(-) diff --git a/linq.d.ts b/linq.d.ts index 3a5c5cd..de28891 100644 --- a/linq.d.ts +++ b/linq.d.ts @@ -112,7 +112,9 @@ declare namespace Enumerable { sequenceEqual(second: T[]): boolean; sequenceEqual(second: T[], compareSelector: (element: T) => TCompare): boolean; orderBy(keySelector: (element: T) => TKey): IOrderedEnumerable; + orderBy(keySelector: (element: T) => TKey, comparer: (first: T, second: T) => number): IOrderedEnumerable; orderByDescending(keySelector: (element: T) => TKey): IOrderedEnumerable; + orderByDescending(keySelector: (element: T) => TKey, comparer: (first: T, second: T) => number): IOrderedEnumerable; reverse(): IEnumerable; shuffle(): IEnumerable; weightedSample(weightSelector: (element: T) => number): IEnumerable; @@ -203,9 +205,11 @@ declare namespace Enumerable { } export interface IOrderedEnumerable extends IEnumerable { - createOrderedEnumerable(keySelector: (element: T) => TKey, descending: boolean): IOrderedEnumerable; + createOrderedEnumerable(keySelector: (element: T) => TKey, comparer: (first: T, second: T) => number, descending: boolean): IOrderedEnumerable; thenBy(keySelector: (element: T) => TKey): IOrderedEnumerable; + thenBy(keySelector: (element: T) => TKey, comparer: (first: T, second: T) => number): IOrderedEnumerable; thenByDescending(keySelector: (element: T) => TKey): IOrderedEnumerable; + thenByDescending(keySelector: (element: T) => TKey, comparer: (first: T, second: T) => number): IOrderedEnumerable; } export interface IDisposableEnumerable extends IEnumerable { diff --git a/linq.js b/linq.js index 586084f..94609db 100644 --- a/linq.js +++ b/linq.js @@ -1541,12 +1541,12 @@ /* Ordering Methods */ - Enumerable.prototype.orderBy = function (keySelector) { - return new OrderedEnumerable(this, keySelector, false); + Enumerable.prototype.orderBy = function (keySelector, comparer) { + return new OrderedEnumerable(this, keySelector, comparer, false); }; - Enumerable.prototype.orderByDescending = function (keySelector) { - return new OrderedEnumerable(this, keySelector, true); + Enumerable.prototype.orderByDescending = function (keySelector, comparer) { + return new OrderedEnumerable(this, keySelector, comparer, true); }; Enumerable.prototype.reverse = function () { @@ -2501,24 +2501,27 @@ // private - var OrderedEnumerable = function (source, keySelector, descending, parent) { + var OrderedEnumerable = function (source, keySelector, comparer, descending, parent) { this.source = source; this.keySelector = Utils.createLambda(keySelector); this.descending = descending; this.parent = parent; + + if (comparer) + this.comparer = Utils.createLambda(comparer); }; OrderedEnumerable.prototype = new Enumerable(); - OrderedEnumerable.prototype.createOrderedEnumerable = function (keySelector, descending) { - return new OrderedEnumerable(this.source, keySelector, descending, this); + OrderedEnumerable.prototype.createOrderedEnumerable = function (keySelector, comparer, descending) { + return new OrderedEnumerable(this.source, keySelector, comparer, descending, this); }; - OrderedEnumerable.prototype.thenBy = function (keySelector) { - return this.createOrderedEnumerable(keySelector, false); + OrderedEnumerable.prototype.thenBy = function (keySelector, comparer) { + return this.createOrderedEnumerable(keySelector, comparer, false); }; - OrderedEnumerable.prototype.thenByDescending = function (keySelector) { - return this.createOrderedEnumerable(keySelector, true); + OrderedEnumerable.prototype.thenByDescending = function (keySelector, comparer) { + return this.createOrderedEnumerable(keySelector, comparer, true); }; OrderedEnumerable.prototype.getEnumerator = function () { @@ -2549,15 +2552,19 @@ ); }; - var SortContext = function (keySelector, descending, child) { + var SortContext = function (keySelector, comparer, descending, child) { this.keySelector = keySelector; this.descending = descending; this.child = child; + this.comparer = comparer; this.keys = null; }; SortContext.create = function (orderedEnumerable, currentContext) { - var context = new SortContext(orderedEnumerable.keySelector, orderedEnumerable.descending, currentContext); + var context = new SortContext( + orderedEnumerable.keySelector, orderedEnumerable.comparer, orderedEnumerable.descending, currentContext + ); + if (orderedEnumerable.parent != null) return SortContext.create(orderedEnumerable.parent, context); return context; }; @@ -2573,7 +2580,9 @@ }; SortContext.prototype.compare = function (index1, index2) { - var comparison = Utils.compare(this.keys[index1], this.keys[index2]); + var comparison = this.comparer ? + this.comparer(this.keys[index1], this.keys[index2]) : + Utils.compare(this.keys[index1], this.keys[index2]); if (comparison == 0) { if (this.child != null) return this.child.compare(index1, index2); diff --git a/package.json b/package.json index 97608f2..5692926 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "linq", "author": "Mihai Ciuraru ", "description": "linq.js - LINQ for JavaScript library packaged for node.js", - "version": "3.2.1", + "version": "3.2.2", "homepage": "https://github.com/mihaifm/linq", "repository": { "type": "git", diff --git a/test/ordering.js b/test/ordering.js index f02a4b2..fb0a7a8 100755 --- a/test/ordering.js +++ b/test/ordering.js @@ -4,7 +4,7 @@ require("../extensions/linq.qunit.js")({'Enumerable': Enumerable}); module("Ordering"); -var expected, actual; // will be removed +var expected, actual; var list = [ { a: 2, b: 4, c: 1 }, @@ -30,6 +30,11 @@ test("orderBy", function () { deepEqual(actual, [1, 7, 31, 51, 51, 85, 99, 823]); Enumerable.rangeTo(10, 1).orderBy("$%5").is(10, 5, 6, 1, 7, 2, 8, 3, 9, 4); + + actual = ['b', 'a', 'd', 'c']; + deepEqual(Enumerable.from(actual).orderBy().toArray(), ['a', 'b', 'c', 'd']); + deepEqual(Enumerable.from(actual).orderBy(x=>x, "(x,y)=>x.localeCompare(y)").toArray(), ['a', 'b', 'c', 'd']); + deepEqual(Enumerable.from(actual).orderBy(x=>x, (x,y)=>xx, (x, y)=>x < y ? -1 : +(x > y)).toArray(), ['d', 'c', 'b', 'a']); }); test("thenBy", function () { @@ -70,6 +79,13 @@ test("thenBy", function () { { a: "z", b: "e", c: "e" } ]; deepEqual(actual, expected); + + actual = Enumerable.from(strlist) + .orderBy(l=>l.a) + .thenBy(l=>l, (x,y) => x.b < y.b ? -1 : x.b > y.b ? 1 : x.c < y.c ? -1 : +(x.c > y.c)) + .toArray(); + + deepEqual(actual, expected); }); test("thenByDescending", function () {