From 5c6d5ad11addcf3ef35081228c1521814893faaa Mon Sep 17 00:00:00 2001 From: Tiago Date: Tue, 2 Oct 2018 02:01:56 -0300 Subject: [PATCH 1/4] Add orderBy --- ShittyLINQ/OrderBy.cs | 110 ++++++++++++++++++++++++++++++++++ ShittyLinqTests/OrdeByTest.cs | 70 ++++++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 ShittyLINQ/OrderBy.cs create mode 100644 ShittyLinqTests/OrdeByTest.cs diff --git a/ShittyLINQ/OrderBy.cs b/ShittyLINQ/OrderBy.cs new file mode 100644 index 0000000..4b95879 --- /dev/null +++ b/ShittyLINQ/OrderBy.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ShittyLINQ +{ + public static partial class Extensions + { + public static IEnumerable OrderBy(this IEnumerable source, Func keySelector) + { + if (source == null) throw new ArgumentNullException("source"); + if (keySelector == null) throw new ArgumentNullException("keySelector"); + List buffer = new List(); + Sortable sortable = new Sortable(keySelector, null, false); + int count = (int)source.Count(); + sortable.ComputeKeys(source.ToList().ToArray(), count); + + int[] map = new int[count]; + for (int i = 0; i < count; i++) map[i] = i; + sortable.QuickSort(map, 0, count - 1); + for (int i = 0; i < source.Count(); i++) + buffer.Add(source.ElementAt(map[i])); + + return buffer; + } + public static IEnumerable OrderBy(this IEnumerable source, Func keySelector, IComparer comparer) + { + if (source == null) throw new ArgumentNullException("source"); + if (keySelector == null) throw new ArgumentNullException("keySelector"); + List buffer = new List(); + Sortable sortable = new Sortable(keySelector, comparer, false); + int count = (int)source.Count(); + sortable.ComputeKeys(source.ToList().ToArray(), count); + + int[] map = new int[count]; + for (int i = 0; i < count; i++) map[i] = i; + sortable.QuickSort(map, 0, count - 1); + for (int i = 0; i < source.Count(); i++) + buffer.Add(source.ElementAt(map[i])); + + return buffer; + } + private class Sortable + { + private Func keySelector; + private IComparer comparer; + private K[] keys; + private bool descending; + + + public Sortable(Func keySelector, IComparer comparer, bool descending) + { + this.keySelector = keySelector; + this.comparer = comparer ?? Comparer.Default; + this.descending = descending; + } + internal void QuickSort(int[] map, int left, int right) + { + do + { + int i = left; + int j = right; + int x = map[i + ((j - i) >> 1)]; + do + { + while (i < map.Length && CompareKeys(x, map[i]) > 0) i++; + while (j >= 0 && CompareKeys(x, map[j]) < 0) j--; + if (i > j) break; + if (i < j) + { + int temp = map[i]; + map[i] = map[j]; + map[j] = temp; + } + i++; + j--; + } while (i <= j); + if (j - left <= right - i) + { + if (left < j) QuickSort(map, left, j); + left = i; + } + else + { + if (i < right) QuickSort(map, i, right); + right = j; + } + } while (left < right); + } + + internal void ComputeKeys(T[] elements, int count) + { + keys = new K[count]; + for (int i = 0; i < count; i++) keys[i] = keySelector(elements[i]); + } + internal int CompareKeys(int index1, int index2) + { + int c = comparer.Compare(keys[index1], keys[index2]); + if (c == 0) + { + return index1 - index2; + } + return descending ? -c : c; + } + + + } + + } +} diff --git a/ShittyLinqTests/OrdeByTest.cs b/ShittyLinqTests/OrdeByTest.cs new file mode 100644 index 0000000..79043bd --- /dev/null +++ b/ShittyLinqTests/OrdeByTest.cs @@ -0,0 +1,70 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Text; +using ShittyLINQ; + +namespace ShittyTests +{ + [TestClass] + public class OrdeByTest + { + [TestMethod] + public void OrderBy_Numbers() + { + int[] numbers = new int[] { 1, 5, 9, 21, 11, 10 }; + + IEnumerable result = numbers.OrderBy(x => x); + + Assert.AreEqual(1, result.ElementAt(0)); + Assert.AreEqual(5, result.ElementAt(1)); + Assert.AreEqual(9, result.ElementAt(2)); + Assert.AreEqual(10, result.ElementAt(3)); + Assert.AreEqual(11, result.ElementAt(4)); + Assert.AreEqual(21, result.ElementAt(5)); + } + [TestMethod] + public void OrderBy_NumbersWithCustomComparer() + { + int[] numbers = new int[] { 314, 782, 0, 93, 65, -1 }; + + IEnumerable result = numbers.OrderBy(n=>n,Comparer.Create((x,y)=> + { + if (x < y) return 1; + if (x > y) return -1; + + return 0; + })); + + Assert.AreEqual(782, result.ElementAt(0)); + Assert.AreEqual(314, result.ElementAt(1)); + Assert.AreEqual(93, result.ElementAt(2)); + Assert.AreEqual(65, result.ElementAt(3)); + Assert.AreEqual(0, result.ElementAt(4)); + Assert.AreEqual(-1, result.ElementAt(5)); + } + [TestMethod] + public void OrderBy_ComplextType() + { + var anonymousType = new[] { + new { name = "Mary", age = 50 }, + new { name = "Jane", age = 10 }, + new { name = "James", age = 70 }, + new { name = "Anthony", age = 15 }, + new { name = "Peter", age = 20 }, + new { name = "Blue", age = 3 }, + new { name = "Jobs", age = 9 }, + }; + + var result = anonymousType.OrderBy(x => x.age); + + Assert.AreEqual(3, result.ElementAt(0).age); + Assert.AreEqual(9, result.ElementAt(1).age); + Assert.AreEqual(10, result.ElementAt(2).age); + Assert.AreEqual(15, result.ElementAt(3).age); + Assert.AreEqual(20, result.ElementAt(4).age); + Assert.AreEqual(50, result.ElementAt(5).age); + Assert.AreEqual(70, result.ElementAt(6).age); + } + } +} From 1f4e60c45ffb32e0319fc4b1a65c14eb1ccf11fb Mon Sep 17 00:00:00 2001 From: Tiago Date: Tue, 2 Oct 2018 08:09:18 -0300 Subject: [PATCH 2/4] refact orderby --- ShittyLINQ/OrderBy.cs | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/ShittyLINQ/OrderBy.cs b/ShittyLINQ/OrderBy.cs index 4b95879..8197616 100644 --- a/ShittyLINQ/OrderBy.cs +++ b/ShittyLINQ/OrderBy.cs @@ -8,27 +8,19 @@ public static partial class Extensions { public static IEnumerable OrderBy(this IEnumerable source, Func keySelector) { - if (source == null) throw new ArgumentNullException("source"); - if (keySelector == null) throw new ArgumentNullException("keySelector"); - List buffer = new List(); - Sortable sortable = new Sortable(keySelector, null, false); - int count = (int)source.Count(); - sortable.ComputeKeys(source.ToList().ToArray(), count); - - int[] map = new int[count]; - for (int i = 0; i < count; i++) map[i] = i; - sortable.QuickSort(map, 0, count - 1); - for (int i = 0; i < source.Count(); i++) - buffer.Add(source.ElementAt(map[i])); - - return buffer; + return OrderedEnumerable(source, keySelector, null, false); } public static IEnumerable OrderBy(this IEnumerable source, Func keySelector, IComparer comparer) + { + return OrderedEnumerable(source, keySelector, comparer, false); + } + private static IEnumerable OrderedEnumerable(IEnumerable source, Func keySelector, IComparer comparer,bool descending) { if (source == null) throw new ArgumentNullException("source"); if (keySelector == null) throw new ArgumentNullException("keySelector"); + List buffer = new List(); - Sortable sortable = new Sortable(keySelector, comparer, false); + Sortable sortable = new Sortable(keySelector, comparer, descending); int count = (int)source.Count(); sortable.ComputeKeys(source.ToList().ToArray(), count); From 075ba5d77f61c59652cbe770d2f66c727bdfa917 Mon Sep 17 00:00:00 2001 From: Tiago Date: Tue, 2 Oct 2018 08:09:34 -0300 Subject: [PATCH 3/4] Add OrderBydDescending --- ShittyLINQ/OrderByDescending.cs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 ShittyLINQ/OrderByDescending.cs diff --git a/ShittyLINQ/OrderByDescending.cs b/ShittyLINQ/OrderByDescending.cs new file mode 100644 index 0000000..83aeefd --- /dev/null +++ b/ShittyLINQ/OrderByDescending.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ShittyLINQ +{ + public static partial class Extensions + { + public static IEnumerable OrderByDescending(this IEnumerable source, Func keySelector) + { + return OrderedEnumerable(source, keySelector, null, true); + } + + public static IEnumerable OrderByDescending(this IEnumerable source, Func keySelector, IComparer comparer) + { + return OrderedEnumerable(source, keySelector, comparer, true); + } + + } +} From bf314b8443b39a6e8e8774d1b42dbfa626884e7a Mon Sep 17 00:00:00 2001 From: Tiago Date: Tue, 2 Oct 2018 08:14:18 -0300 Subject: [PATCH 4/4] test --- ShittyLinqTests/OrderByDescendingTest.cs | 70 ++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 ShittyLinqTests/OrderByDescendingTest.cs diff --git a/ShittyLinqTests/OrderByDescendingTest.cs b/ShittyLinqTests/OrderByDescendingTest.cs new file mode 100644 index 0000000..67cc29b --- /dev/null +++ b/ShittyLinqTests/OrderByDescendingTest.cs @@ -0,0 +1,70 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Text; +using ShittyLINQ; + +namespace ShittyTests +{ + [TestClass] + public class OrderByDescendingTest + { + [TestMethod] + public void OrderBy_Numbers() + { + int[] numbers = new int[] { 1, 5, 9, 21, 11, 10 }; + + IEnumerable result = numbers.OrderByDescending(x => x); + + Assert.AreEqual(21, result.ElementAt(0)); + Assert.AreEqual(11, result.ElementAt(1)); + Assert.AreEqual(10, result.ElementAt(2)); + Assert.AreEqual(9, result.ElementAt(3)); + Assert.AreEqual(5, result.ElementAt(4)); + Assert.AreEqual(1, result.ElementAt(5)); + } + [TestMethod] + public void OrderBy_NumbersWithCustomComparer() + { + int[] numbers = new int[] { 314, 782, 0, 93, 65, -1 }; + + IEnumerable result = numbers.OrderByDescending(n=>n,Comparer.Create((x,y)=> + { + if (x < y) return 1; + if (x > y) return -1; + + return 0; + })); + + Assert.AreEqual(-1, result.ElementAt(0)); + Assert.AreEqual(0, result.ElementAt(1)); + Assert.AreEqual(65, result.ElementAt(2)); + Assert.AreEqual(93, result.ElementAt(3)); + Assert.AreEqual(314, result.ElementAt(4)); + Assert.AreEqual(782, result.ElementAt(5)); + } + [TestMethod] + public void OrderBy_ComplextType() + { + var anonymousType = new[] { + new { name = "Mary", age = 50 }, + new { name = "Jane", age = 10 }, + new { name = "James", age = 70 }, + new { name = "Anthony", age = 15 }, + new { name = "Peter", age = 20 }, + new { name = "Blue", age = 3 }, + new { name = "Jobs", age = 9 }, + }; + + var result = anonymousType.OrderByDescending(x => x.age); + + Assert.AreEqual(70, result.ElementAt(0).age); + Assert.AreEqual(50, result.ElementAt(1).age); + Assert.AreEqual(20, result.ElementAt(2).age); + Assert.AreEqual(15, result.ElementAt(3).age); + Assert.AreEqual(10, result.ElementAt(4).age); + Assert.AreEqual(9, result.ElementAt(5).age); + Assert.AreEqual(3, result.ElementAt(6).age); + } + } +}