ListAligner - Houzkin/TreeStructures GitHub Wiki
public class ListAligner<S,T,TList> where TList : IList<T> {
/// <summary>
/// Initializes a new instance of the <see cref="ListAligner{T, U, TList}"/> class to reorder a list based on a given sequence.
/// </summary>
/// <param name="editList">The target list to be aligned.</param>
/// <param name="convert">A function to convert an element of type <typeparamref name="S"/> to type <typeparamref name="T"/>.</param>
/// <param name="equality">A function that determines whether an element of type <typeparamref name="T"/> is equal to an element of type <typeparamref name="S"/>.</param>
/// <param name="insert">A function to insert an element into the list. By default, <see cref="IList{T}.Insert(int, T)"/> is used.</param>
/// <param name="replace">A function to replace an element in the list. By default, assignment via the indexer of <see cref="IList{T}"/> is used.</param>
/// <param name="move">A function to move an element within the list. By default, this is handled via manual insertion and deletion.</param>
/// <param name="remove">A function to remove an element from the list. By default, <see cref="IList{T}.RemoveAt(int)"/> is used.</param>
/// <param name="clear">A function to clear the list. By default, <see cref="ICollection{T}.Clear()"/> is used.</param>
public ListAligner(TList editList, Func<S, T> convert, Func<S, T, bool> equality, Action<TList, int, T>? insert = null, Action<TList, int, T>? replace = null, Action<TList, int, int>? move = null, Action<TList, int>? remove=null, Action<TList>? clear=null) { }
/// <summary>Aligns the list according to the specified order.</summary>
/// <param name="order">A collection defining the desired order of elements in the list.</param>
public void AlignBy(IEnumerable<S> order) { }
}
public class ListAligner<T, TList> : ListAligner<T,T,TList> where TList : IList<T> {
public ListAligner(TList editList,
Action<TList, int, T>? insert = null, Action<TList, int, T>? replace = null,
Action<TList, int>? remove = null, Action<TList, int, int>? move = null, Action<TList>? clear = null, IEqualityComparer<T>? comparer = null)
: base(editList, x => x, (x, y) => comparer?.Equals(x, y) ?? EqualityComparer<T>.Default.Equals(x, y), insert, replace, move, remove, clear) {
}
}Extension methods
public static void AlignBy<T>(this IList<T> self,IEnumerable<T> sequence, IEqualityComparer<T>? equality = null) {
var editor = new ListAligner<T, IList<T>>(self, comparer: equality);
editor.AlignBy(sequence);
}
public static void AlignBy<T>(this ObservableCollection<T> self, IEnumerable<T> sequence, IEqualityComparer<T>? equality = null) {
var editer = new ListAligner<T, ObservableCollection<T>>(self, move: (list, ord, to) => { list.Move(ord, to); }, comparer: equality);
editer.AlignBy(sequence);
}
public static void AlignBy<S,T>(this ObservableCollection<T> self, IEnumerable<S> sequence,Func<S,T> convert,Func<S,T,bool> equality) {
var editer = new ListAligner<S, T, ObservableCollection<T>>(self, convert, equality, move: (list, ord, to) => list.Move(ord, to));
editer.AlignBy(sequence);
} var list = new ObservableCollection<int>(new[] { 10, 21, 32, 43, 5, 65, 70, 18, 29 });
//list.CollectionChanged += (s, e) => {
// Console.WriteLine($"{e.Action}, newIndex:{e.NewStartingIndex}, oldIndex:{e.OldStartingIndex} newItems:{string.Join(',', e.NewItems?.OfType<int>().Select(x => x.ToString()) ?? new string[] { })}, oldItems:{string.Join(',', e.OldItems?.OfType<int>().Select(x => x.ToString()) ?? new string[] { })}");
// Console.WriteLine(string.Join(", ", list)+"\n");
//};
Console.WriteLine(string.Join(", ", list)+"\n");
//10, 21, 32, 43, 5, 65, 70, 18, 29
list.AlignBy(list.OrderBy(x => x).TakeWhile(x => x < 50));
Console.WriteLine(string.Join(", ", list));
// 5, 10, 18, 21, 29, 32, 43
list.AlignBy(Enumerable.Range(8, 4));
Console.WriteLine(string.Join(", ", list));
// 8, 9, 10, 11
list.AlignBy(list.AsEnumerable().Reverse().Append(11).Append(11));
Console.WriteLine(string.Join(", ", list));
// 11, 10, 9, 8, 11, 11