Created
July 31, 2012 07:21
-
-
Save turbanoff/3214469 to your computer and use it in GitHub Desktop.
.net source
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
public static class Enumerable | |
{ | |
internal abstract class EnumerableSorter<TElement> | |
{ | |
internal abstract void ComputeKeys(TElement[] elements, int count); | |
internal abstract int CompareKeys(int index1, int index2); | |
internal int[] Sort(TElement[] elements, int count) | |
{ | |
ComputeKeys(elements, count); | |
int[] map = new int[count]; | |
for (int i = 0; i < count; i++) map[i] = i; | |
QuickSort(map, 0, count - 1); | |
return map; | |
} | |
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); | |
} | |
} | |
public interface IOrderedEnumerable<TElement> : IEnumerable<TElement> | |
{ | |
} | |
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) | |
{ | |
return new OrderedEnumerable<TSource, TKey>(source, keySelector, null, false); | |
} | |
internal abstract class OrderedEnumerable<TElement> : IOrderedEnumerable<TElement> | |
{ | |
internal IEnumerable<TElement> source; | |
public IEnumerator<TElement> GetEnumerator() | |
{ | |
Buffer<TElement> buffer = new Buffer<TElement>(source); | |
if (buffer.count > 0) | |
{ | |
EnumerableSorter<TElement> sorter = GetEnumerableSorter(null); | |
int[] map = sorter.Sort(buffer.items, buffer.count); | |
sorter = null; | |
for (int i = 0; i < buffer.count; i++) yield return buffer.items[map[i]]; | |
} | |
} | |
internal abstract EnumerableSorter<TElement> GetEnumerableSorter(EnumerableSorter<TElement> next); | |
IEnumerator IEnumerable.GetEnumerator() | |
{ | |
return GetEnumerator(); | |
} | |
} | |
internal class OrderedEnumerable<TElement, TKey> : OrderedEnumerable<TElement> | |
{ | |
internal OrderedEnumerable<TElement> parent; | |
internal Func<TElement, TKey> keySelector; | |
internal IComparer<TKey> comparer; | |
internal bool descending; | |
internal OrderedEnumerable(IEnumerable<TElement> source, Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending) | |
{ | |
if (source == null) throw new ArgumentNullException("source"); | |
if (keySelector == null) throw new ArgumentNullException("keySelector"); | |
this.source = source; | |
this.parent = null; | |
this.keySelector = keySelector; | |
this.comparer = comparer ?? Comparer<TKey>.Default; | |
this.descending = descending; | |
} | |
internal override EnumerableSorter<TElement> GetEnumerableSorter(EnumerableSorter<TElement> next) | |
{ | |
EnumerableSorter<TElement> sorter = new EnumerableSorter<TElement, TKey>(keySelector, comparer, descending, next); | |
if (parent != null) sorter = parent.GetEnumerableSorter(sorter); | |
return sorter; | |
} | |
} | |
internal class EnumerableSorter<TElement, TKey> : EnumerableSorter<TElement> | |
{ | |
internal Func<TElement, TKey> keySelector; | |
internal IComparer<TKey> comparer; | |
internal bool descending; | |
internal EnumerableSorter<TElement> next; | |
internal TKey[] keys; | |
internal EnumerableSorter(Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending, EnumerableSorter<TElement> next) | |
{ | |
this.keySelector = keySelector; | |
this.comparer = comparer; | |
this.descending = descending; | |
this.next = next; | |
} | |
internal override void ComputeKeys(TElement[] elements, int count) | |
{ | |
keys = new TKey[count]; | |
for (int i = 0; i < count; i++) keys[i] = keySelector(elements[i]); | |
if (next != null) next.ComputeKeys(elements, count); | |
} | |
internal override int CompareKeys(int index1, int index2) | |
{ | |
int c = comparer.Compare(keys[index1], keys[index2]); | |
if (c == 0) | |
{ | |
if (next == null) return index1 - index2; | |
return next.CompareKeys(index1, index2); | |
} | |
return descending ? -c : c; | |
} | |
} | |
struct Buffer<TElement> | |
{ | |
internal TElement[] items; | |
internal int count; | |
internal Buffer(IEnumerable<TElement> source) | |
{ | |
TElement[] items = null; | |
int count = 0; | |
ICollection<TElement> collection = source as ICollection<TElement>; | |
if (collection != null) | |
{ | |
count = collection.Count; | |
if (count > 0) | |
{ | |
items = new TElement[count]; | |
collection.CopyTo(items, 0); | |
} | |
} | |
else | |
{ | |
foreach (TElement item in source) | |
{ | |
if (items == null) | |
{ | |
items = new TElement[4]; | |
} | |
else if (items.Length == count) | |
{ | |
TElement[] newItems = new TElement[checked(count * 2)]; | |
Array.Copy(items, 0, newItems, 0, count); | |
items = newItems; | |
} | |
items[count] = item; | |
count++; | |
} | |
} | |
this.items = items; | |
this.count = count; | |
} | |
} | |
} | |
public class Program | |
{ | |
private static void Main(string[] args) | |
{ | |
List<int> list = new List<int> { -5, 1, -4, -11, 0, 3, 10, 4 }; | |
var qwerty = list.OrderBy(i => i); | |
foreach (var m in qwerty) | |
{ | |
Console.WriteLine(m); | |
} | |
Console.ReadKey(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
public static class Enumerable | |
{ | |
internal abstract class EnumerableSorter<TElement> | |
{ | |
internal abstract void ComputeKeys(TElement[] elements, int count); | |
internal abstract int CompareKeys(int index1, int index2); | |
internal int[] Sort(TElement[] elements, int count) | |
{ | |
ComputeKeys(elements, count); | |
int[] map = new int[count]; | |
for (int i = 0; i < count; i++) map[i] = i; | |
QuickSort(map, 0, count - 1); | |
return map; | |
} | |
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); | |
} | |
} | |
public interface IOrderedEnumerable<TElement> : IEnumerable<TElement> | |
{ | |
} | |
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) | |
{ | |
return new OrderedEnumerable<TSource, TKey>(source, keySelector, null, false); | |
} | |
internal abstract class OrderedEnumerable<TElement> : IOrderedEnumerable<TElement> | |
{ | |
internal IEnumerable<TElement> source; | |
public IEnumerator<TElement> GetEnumerator() | |
{ | |
Buffer<TElement> buffer = new Buffer<TElement>(source); | |
if (buffer.count > 0) | |
{ | |
EnumerableSorter<TElement> sorter = GetEnumerableSorter(null); | |
int[] map = sorter.Sort(buffer.items, buffer.count); | |
sorter = null; | |
for (int i = 0; i < buffer.count; i++) yield return buffer.items[map[i]]; | |
} | |
} | |
internal abstract EnumerableSorter<TElement> GetEnumerableSorter(EnumerableSorter<TElement> next); | |
IEnumerator IEnumerable.GetEnumerator() | |
{ | |
return GetEnumerator(); | |
} | |
} | |
internal class OrderedEnumerable<TElement, TKey> : OrderedEnumerable<TElement> | |
{ | |
internal OrderedEnumerable<TElement> parent; | |
internal Func<TElement, TKey> keySelector; | |
internal IComparer<TKey> comparer; | |
internal bool descending; | |
internal OrderedEnumerable(IEnumerable<TElement> source, Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending) | |
{ | |
if (source == null) throw new ArgumentNullException("source"); | |
if (keySelector == null) throw new ArgumentNullException("keySelector"); | |
this.source = source; | |
this.parent = null; | |
this.keySelector = keySelector; | |
this.comparer = comparer ?? Comparer<TKey>.Default; | |
this.descending = descending; | |
} | |
internal override EnumerableSorter<TElement> GetEnumerableSorter(EnumerableSorter<TElement> next) | |
{ | |
EnumerableSorter<TElement> sorter = new EnumerableSorter<TElement, TKey>(keySelector, comparer, descending, next); | |
if (parent != null) sorter = parent.GetEnumerableSorter(sorter); | |
return sorter; | |
} | |
} | |
internal class EnumerableSorter<TElement, TKey> : EnumerableSorter<TElement> | |
{ | |
internal Func<TElement, TKey> keySelector; | |
internal IComparer<TKey> comparer; | |
internal bool descending; | |
internal EnumerableSorter<TElement> next; | |
internal TKey[] keys; | |
internal EnumerableSorter(Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending, EnumerableSorter<TElement> next) | |
{ | |
this.keySelector = keySelector; | |
this.comparer = comparer; | |
this.descending = descending; | |
this.next = next; | |
} | |
internal override void ComputeKeys(TElement[] elements, int count) | |
{ | |
keys = new TKey[count]; | |
for (int i = 0; i < count; i++) keys[i] = keySelector(elements[i]); | |
if (next != null) next.ComputeKeys(elements, count); | |
} | |
internal override int CompareKeys(int index1, int index2) | |
{ | |
int c = comparer.Compare(keys[index1], keys[index2]); | |
if (c == 0) | |
{ | |
if (next == null) return index1 - index2; | |
return next.CompareKeys(index1, index2); | |
} | |
return descending ? -c : c; | |
} | |
} | |
struct Buffer<TElement> | |
{ | |
internal TElement[] items; | |
internal int count; | |
internal Buffer(IEnumerable<TElement> source) | |
{ | |
TElement[] items = null; | |
int count = 0; | |
ICollection<TElement> collection = source as ICollection<TElement>; | |
if (collection != null) | |
{ | |
count = collection.Count; | |
if (count > 0) | |
{ | |
items = new TElement[count]; | |
collection.CopyTo(items, 0); | |
} | |
} | |
else | |
{ | |
foreach (TElement item in source) | |
{ | |
if (items == null) | |
{ | |
items = new TElement[4]; | |
} | |
else if (items.Length == count) | |
{ | |
TElement[] newItems = new TElement[checked(count * 2)]; | |
Array.Copy(items, 0, newItems, 0, count); | |
items = newItems; | |
} | |
items[count] = item; | |
count++; | |
} | |
} | |
this.items = items; | |
this.count = count; | |
} | |
} | |
} | |
public class Program | |
{ | |
private static void Main(string[] args) | |
{ | |
List<int> list = new List<int> { -5, 1, -4, -11, 0, 3, 10, 4 }; | |
var qwerty = list.OrderBy(i => i); | |
foreach (var m in qwerty) | |
{ | |
Console.WriteLine(m); | |
} | |
Console.ReadKey(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment