diff --git a/ShittyLINQ/OrderBy.cs b/ShittyLINQ/OrderBy.cs new file mode 100644 index 0000000..8197616 --- /dev/null +++ b/ShittyLINQ/OrderBy.cs @@ -0,0 +1,102 @@ +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) + { + 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, descending); + 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/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); + } + + } +} 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); + } + } +} 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); + } + } +}