| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 | using System;using System.Collections.Generic;using System.Linq;namespace Ips.Library.Basic{    public static class ListExtensions    {        public static void InsertRange<T>(this IList<T> source, int index, IEnumerable<T> items)        {            foreach (var item in items)            {                source.Insert(index++, item);            }        }        public static int FindIndex<T>(this IList<T> source, Predicate<T> selector)        {            for (var i = 0; i < source.Count; ++i)            {                if (selector(source[i]))                {                    return i;                }            }            return -1;        }        public static void AddFirst<T>(this IList<T> source, T item)        {            source.Insert(0, item);        }        public static void AddLast<T>(this IList<T> source, T item)        {            source.Insert(source.Count, item);        }        public static void InsertAfter<T>(this IList<T> source, T existingItem, T item)        {            var index = source.IndexOf(existingItem);            if (index < 0)            {                source.AddFirst(item);                return;            }            source.Insert(index + 1, item);        }        public static void InsertAfter<T>(this IList<T> source, Predicate<T> selector, T item)        {            var index = source.FindIndex(selector);            if (index < 0)            {                source.AddFirst(item);                return;            }            source.Insert(index + 1, item);        }        public static void InsertBefore<T>(this IList<T> source, T existingItem, T item)        {            var index = source.IndexOf(existingItem);            if (index < 0)            {                source.AddLast(item);                return;            }            source.Insert(index, item);        }        public static void InsertBefore<T>(this IList<T> source, Predicate<T> selector, T item)        {            var index = source.FindIndex(selector);            if (index < 0)            {                source.AddLast(item);                return;            }            source.Insert(index, item);        }        public static void ReplaceWhile<T>(this IList<T> source, Predicate<T> selector, T item)        {            for (int i = 0; i < source.Count; i++)            {                if (selector(source[i]))                {                    source[i] = item;                }            }        }        public static void ReplaceWhile<T>(this IList<T> source, Predicate<T> selector, Func<T, T> itemFactory)        {            for (int i = 0; i < source.Count; i++)            {                var item = source[i];                if (selector(item))                {                    source[i] = itemFactory(item);                }            }        }        public static void ReplaceOne<T>(this IList<T> source, Predicate<T> selector, T item)        {            for (int i = 0; i < source.Count; i++)            {                if (selector(source[i]))                {                    source[i] = item;                    return;                }            }        }        public static void ReplaceOne<T>(this IList<T> source, Predicate<T> selector, Func<T, T> itemFactory)        {            for (int i = 0; i < source.Count; i++)            {                var item = source[i];                if (selector(item))                {                    source[i] = itemFactory(item);                    return;                }            }        }        public static void ReplaceOne<T>(this IList<T> source, T item, T replaceWith)        {            for (int i = 0; i < source.Count; i++)            {                if (Comparer<T>.Default.Compare(source[i], item) == 0)                {                    source[i] = replaceWith;                    return;                }            }        }        public static void MoveItem<T>(this List<T> source, Predicate<T> selector, int targetIndex)        {            var currentIndex = source.FindIndex(0, selector);            if (currentIndex == targetIndex)            {                return;            }            var item = source[currentIndex];            source.RemoveAt(currentIndex);            source.Insert(targetIndex, item);        }        public static T GetOrAdd<T>(this IList<T> source, Func<T, bool> selector, Func<T> factory)        {            var item = source.FirstOrDefault(selector);            if (item == null)            {                item = factory();                source.Add(item);            }            return item;        }        public static List<T> SortByDependencies<T>(            this IEnumerable<T> source,            Func<T, IEnumerable<T>> getDependencies,            IEqualityComparer<T> comparer = null)        {            var sorted = new List<T>();            var visited = new Dictionary<T, bool>(comparer);            foreach (var item in source)            {                SortByDependenciesVisit(item, getDependencies, sorted, visited);            }            return sorted;        }        private static void SortByDependenciesVisit<T>(T item, Func<T, IEnumerable<T>> getDependencies, List<T> sorted,            Dictionary<T, bool> visited)        {            bool inProcess;            var alreadyVisited = visited.TryGetValue(item, out inProcess);            if (alreadyVisited)            {                if (inProcess)                {                    throw new ArgumentException("Cyclic dependency found! Item: " + item);                }            }            else            {                visited[item] = true;                var dependencies = getDependencies(item);                if (dependencies != null)                {                    foreach (var dependency in dependencies)                    {                        SortByDependenciesVisit(dependency, getDependencies, sorted, visited);                    }                }                visited[item] = false;                sorted.Add(item);            }        }    }}
 |