ListAligner - Houzkin/TreeStructures GitHub Wiki

ListAligner

Member

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);
}

Example

    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
⚠️ **GitHub.com Fallback** ⚠️