Skip to content

Instantly share code, notes, and snippets.

@turbanoff
Created July 31, 2012 07:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save turbanoff/3214469 to your computer and use it in GitHub Desktop.
Save turbanoff/3214469 to your computer and use it in GitHub Desktop.
.net source
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();
}
}
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