Feedback

C# - Einfaches LINQ-Funktionen

Veröffentlicht von am 30.06.2015
(0 Bewertungen)
Ich verwende häufig LINQ, deshalb finde ich es auch sehr schade, dass es unter Mono nicht einsetzbar ist. :(

Zu diesem Zwecke habe ich mir einige eigene LINQ-Artige Funktionen entwickelt.

Der Code sollte selbsterklärend sein.
GFU-Schulungen  [Anzeige]

Visual Studio Team Foundation Server 2017/2015 (TFS) für Projektmitglieder - Kompakt

Nach Teilnahme an dieser Schulung sind Ihnen die Grundlagen von ALM geläufig. Sie planen und steuern Projekte effizient mit dem Visual Studio Team Foundation Server.

XML und .NET Überblick

Um auf dem neuesten Wissensstand zu sein, sollten Sie unser aktuelles ASP .NET Komplett Seminar belegen.
Nach dem Seminar kennen Sie die wichtigsten Strömungen in der Software-Technologie

// 
// 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;
	}
}	
Abgelegt unter LINQ, Mono, Daten, Verarbeitung.

Kommentare zum Snippet

 

Logge dich ein, um hier zu kommentieren!