//
// Abgeleitete Funktionen bekommen einen einen Wert vom Typen T
// und müssen zurückgeben, ob der Wert das gewünschte Kriterium erfüllt (true) oder nicht (false);
//
public delegate bool QueryServiceConditionFunc<T>(T value,int index);
//
// Diese Funktion erhält ein Objekt des Typens T und kann mit diesem nun arbeiten.
//
public delegate void QueryServiceFunc<T>(T value,int index);
//
// Da c# für die MonoRuntime derzeit scheinbar keine LINQ-Ausdrücke enthält,
// ist hier eine Implementierung, die einige der Funktionen übernehmen kann.
//
public static class QueryService
{
//
// Verwandelt eine IEnumerable in ein Array.
//
public static T[] ToArray<T>(this IEnumerable e)
{
var n = e.Count();
T[] arr = new T[n];
e.ForEach<T>((v, i) => {
arr[i] = v;
});
return arr;
}
//
// Versucht aus einer Sammlung von Elementen alle zu finden,
// für die eine bestimmte Bedingung gilt und gibt diese als neue Liste zurück.
//
public static T[] Select<T>(this IEnumerable e, QueryServiceConditionFunc<T> f)
{
List<T> res = new List<T>();
e.ForEach<T>((v, i) => {
if (f(v, i)) // Wenn die bedingung stimmt, zur Liste hinzufügen
res.Add(v);
});
return res.ToArray();
}
//
// Fügt alle Elemente in eine große Liste zusammen und gibt diese zurück.
//
public static T[] Join<T>(this IEnumerable e, params IEnumerable[] values)
{
List<T> res = new List<T>();
e.ForEach<T>((v, i) => {
res.Add(v); });
foreach (var item in values) {
item.ForEach<T>((v, i) => {
res.Add(v); });
}
return res.ToArray();
}
//
// Zählt nach, für wie viele Elemente die Bedingung gilt.
//
public static int CountContains<T>(this IEnumerable e, QueryServiceConditionFunc<T> f)
{
return e.Select(f).Length;
}
//
// Bestimmt, ob in der List der bestimmte Wert vorkomment
//
public static bool Contains<T>(this IEnumerable e, T value)
{
var ee = e.GetEnumerator();
do {
if (Object.Equals((T)ee.Current, value))
return true;
} while (ee.MoveNext());
return false; //Keine Übereinstimmung gefunden!
}
//
// Gibt eine Liste von Werten zurück, die in beiden Listen vorkommen.
//
public static T[] Union<T>(this IEnumerable e, IEnumerable values)
{
Dictionary<T, int> d = new Dictionary<T, int>();
foreach (var item in e) {
d.Add((T)item, 0);
}
foreach (var item in values) {
if (d.ContainsKey((T)item))
d[(T)item]++; // Auf +1 erhöhen
else {
d.Add((T)item, 0);
}
}
List<T> res = new List<T>();
foreach (var item in d) {
if (item.Value >= 1)
res.Add(item.Key);
}
return res.ToArray();
}
//
// Durchläuft für jedes Eleemtn eine Funktion func.
//
public static void ForEach<T>(this IEnumerable e, QueryServiceFunc<T> func)
{
var _enumerator = e.GetEnumerator();
_enumerator.Reset();
int index = 0;
do {
func((T)_enumerator.Current, index);
index++;
} while (_enumerator.MoveNext());
}
//
// Addiert alle Werte, die in der Sammlung vorkommen.
// Achtung: Der Type T muss eine Zahl sein (int).
// Wenn andere Typen notwendig sind (uint etc.) einfach umschreiben.
//
public static int Sum<T>(this IEnumerable e)
{
int sum = 0;
e.ForEach<int>((v, i) => {
sum += v; });
return sum;
}
//
// Bestimmt den durchschnittlichen Wert aus der Liste.
// Achtung: Der Type T muss eine Zahl sein (int).
// Wenn andere Typen notwendig sind (uint etc.) einfach umschreiben.
//
public static int Average<T>(this IEnumerable e)
{
return e.Sum<T>() / e.Count();
}
//
// Bestimt den größten Wert.
// Achtung: Der Type T muss eine Zahl sein (int).
// Wenn andere Typen notwendig sind (uint etc.) einfach umschreiben.
//
public static int Max<T>(this IEnumerable e)
{
int max = int.MinValue;
e.ForEach<int>((v, i) => {
if (v > max)
max = v;
});
return max;
}
//
// Bestimmt den kleinsten Wert.
// Achtung: Der Type T muss eine Zahl sein (int).
// Wenn andere Typen notwendig sind (uint etc.) einfach umschreiben.
//
public static int Min<T>(this IEnumerable e)
{
int min = int.MaxValue;
e.ForEach<int>((v, i) => {
if (v < min)
min = v;
});
return min;
}
//
// Gibt das erste Elment oder Null zurück.
//
public static T FirstOrDefault<T>(this IEnumerable e)
{
var ee = e.GetEnumerator();
ee.Reset();
if (ee.MoveNext())
return (T)ee.Current;
return default(T); //return null
}
//
// Versucht das Elemenent aus der Position zu erhalten.
// Soltle es dieses nicht geben, wird null zurückgeben.
// Es drüfgen keinen negativen Indizien verwendet werden.
//
public static T GetAt<T>(this IEnumerable e, uint index)
{
T ret = default(T);
var ee = e.GetEnumerator();
ee.Reset();
for (uint i = 0; i <= index; i++) {
if (!ee.MoveNext()) // Die Liste ist schon zuende
return ret;
else { // Auf Index prüfen
if (i == index) // Der Index passt
return (T)ee.Current;
}
}
return ret;
}
//
// Zählt die Anzahl der Elemente in der Liste.
// Soltlen andere Zahlentypen benötigt werden (uint, long...),
// so muss die Funktion abgeändert werden.
//
public static int Count(this IEnumerable e)
{
var _enumerator = e.GetEnumerator();
int c = 0;
do {
c++;
} while(_enumerator.MoveNext());
return c;
}
}