You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3098 lines
96 KiB
3098 lines
96 KiB
5 years ago
|
// Needed for NET40
|
||
|
#if !NET_4_6
|
||
|
using System;
|
||
|
using System.Collections;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Collections.ObjectModel;
|
||
|
using System.Linq;
|
||
|
|
||
|
using LinqInternal.Collections.Specialized;
|
||
|
using LinqInternal.Collections.ThreadSafe;
|
||
|
using LinqInternal.Core;
|
||
|
|
||
|
namespace LinqInternal.Collections
|
||
|
{
|
||
|
[System.Diagnostics.DebuggerNonUserCode]
|
||
|
internal static partial class Extensions
|
||
|
{
|
||
|
public static void Add<T>(this Stack<T> stack, T item)
|
||
|
{
|
||
|
if (stack == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("stack");
|
||
|
}
|
||
|
stack.Push(item);
|
||
|
}
|
||
|
|
||
|
public static void Add<T>(this Queue<T> queue, T item)
|
||
|
{
|
||
|
if (queue == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("queue");
|
||
|
}
|
||
|
queue.Enqueue(item);
|
||
|
}
|
||
|
|
||
|
public static T[] AddFirst<T>(this IList<T> list, T item)
|
||
|
{
|
||
|
if (list == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("list");
|
||
|
}
|
||
|
// Copyright (c) Microsoft. All rights reserved.
|
||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||
|
var res = new T[list.Count + 1];
|
||
|
res[0] = item;
|
||
|
list.CopyTo(res, 1);
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
public static void CanCopyTo(int count, Array array)
|
||
|
{
|
||
|
if (array == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("array");
|
||
|
}
|
||
|
if (count > array.Length)
|
||
|
{
|
||
|
throw new ArgumentException("The array can not contain the number of elements.", "array");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void CanCopyTo(int count, Array array, int arrayIndex)
|
||
|
{
|
||
|
if (array == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("array");
|
||
|
}
|
||
|
if (arrayIndex < 0)
|
||
|
{
|
||
|
throw new ArgumentOutOfRangeException("arrayIndex", "Non-negative number is required.");
|
||
|
}
|
||
|
if (count > array.Length - arrayIndex)
|
||
|
{
|
||
|
throw new ArgumentException("The array can not contain the number of elements.", "array");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void CanCopyTo<T>(int count, T[] array)
|
||
|
{
|
||
|
if (array == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("array");
|
||
|
}
|
||
|
if (count > array.Length)
|
||
|
{
|
||
|
throw new ArgumentException("The array can not contain the number of elements.", "array");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void CanCopyTo<T>(int count, T[] array, int arrayIndex)
|
||
|
{
|
||
|
if (array == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("array");
|
||
|
}
|
||
|
if (arrayIndex < 0)
|
||
|
{
|
||
|
throw new ArgumentOutOfRangeException("arrayIndex", "Non-negative number is required.");
|
||
|
}
|
||
|
if (count > array.Length - arrayIndex)
|
||
|
{
|
||
|
throw new ArgumentException("The array can not contain the number of elements.", "array");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void CanCopyTo<T>(T[] array, int arrayIndex, int countLimit)
|
||
|
{
|
||
|
if (array == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("array");
|
||
|
}
|
||
|
if (arrayIndex < 0)
|
||
|
{
|
||
|
throw new ArgumentOutOfRangeException("arrayIndex", "Non-negative number is required.");
|
||
|
}
|
||
|
if (countLimit < 0)
|
||
|
{
|
||
|
throw new ArgumentOutOfRangeException("countLimit", "Non-negative number is required.");
|
||
|
}
|
||
|
if (countLimit > array.Length - arrayIndex)
|
||
|
{
|
||
|
throw new ArgumentException("The array can not contain the number of elements.", "array");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<T> Clone<T>(this IEnumerable<T> target)
|
||
|
{
|
||
|
return new List<T>(target);
|
||
|
}
|
||
|
|
||
|
public static void Consume<T>(this IEnumerable<T> source)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
foreach (var element in source)
|
||
|
{
|
||
|
GC.KeepAlive(element);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static bool ContainsAny<T>(this IEnumerable<T> source, IEnumerable<T> items)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (items == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("items");
|
||
|
}
|
||
|
IEqualityComparer<T> comparer = EqualityComparer<T>.Default;
|
||
|
var localCollection = AsCollection(source);
|
||
|
foreach (var item in items)
|
||
|
{
|
||
|
if (localCollection.Contains(item, comparer))
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public static bool ContainsAny<T>(this IEnumerable<T> source, IEnumerable<T> items, IEqualityComparer<T> comparer)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (items == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("items");
|
||
|
}
|
||
|
comparer = comparer ?? EqualityComparer<T>.Default;
|
||
|
var localCollection = AsCollection(source);
|
||
|
foreach (var item in items)
|
||
|
{
|
||
|
if (localCollection.Contains(item, comparer))
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public static List<TOutput> ConvertAll<T, TOutput>(this IEnumerable<T> source, Func<T, TOutput> converter)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (converter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("converter");
|
||
|
}
|
||
|
var result = new List<TOutput>();
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
result.Add(converter(item));
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
public static TList ConvertAll<T, TOutput, TList>(this IEnumerable<T> source, Func<T, TOutput> converter)
|
||
|
where TList : ICollection<TOutput>, new()
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (converter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("converter");
|
||
|
}
|
||
|
var result = new TList();
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
result.Add(converter(item));
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
public static List<TOutput> ConvertFiltered<T, TOutput>(this IEnumerable<T> source, Func<T, TOutput> converter, Predicate<T> filter)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (converter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("converter");
|
||
|
}
|
||
|
if (filter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("filter");
|
||
|
}
|
||
|
var result = new List<TOutput>();
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (filter(item))
|
||
|
{
|
||
|
result.Add(converter(item));
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
public static List<TOutput> ConvertFiltered<T, TOutput>(this IEnumerable<T> source, Func<T, TOutput> converter, Func<T, int, bool> filter)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (converter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("converter");
|
||
|
}
|
||
|
if (filter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("filter");
|
||
|
}
|
||
|
var index = 0;
|
||
|
var result = new List<TOutput>();
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (filter(item, index))
|
||
|
{
|
||
|
result.Add(converter(item));
|
||
|
}
|
||
|
index++;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
public static TList ConvertFiltered<T, TOutput, TList>(this IEnumerable<T> source, Func<T, TOutput> converter, Predicate<T> filter)
|
||
|
where TList : ICollection<TOutput>, new()
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (converter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("converter");
|
||
|
}
|
||
|
if (filter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("filter");
|
||
|
}
|
||
|
var result = new TList();
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (filter(item))
|
||
|
{
|
||
|
result.Add(converter(item));
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
public static TList ConvertFiltered<T, TOutput, TList>(this IEnumerable<T> source, Func<T, TOutput> converter, Func<T, int, bool> filter)
|
||
|
where TList : ICollection<TOutput>, new()
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (converter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("converter");
|
||
|
}
|
||
|
if (filter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("filter");
|
||
|
}
|
||
|
var index = 0;
|
||
|
var result = new TList();
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (filter(item, index))
|
||
|
{
|
||
|
result.Add(converter(item));
|
||
|
}
|
||
|
index++;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
public static List<KeyValuePair<int, TOutput>> ConvertIndexed<T, TOutput>(this IEnumerable<T> source, Func<T, TOutput> converter, Predicate<T> filter)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (converter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("converter");
|
||
|
}
|
||
|
if (filter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("filter");
|
||
|
}
|
||
|
var index = 0;
|
||
|
var result = new List<KeyValuePair<int, TOutput>>();
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (filter(item))
|
||
|
{
|
||
|
result.Add(new KeyValuePair<int, TOutput>(index, converter(item)));
|
||
|
}
|
||
|
index++;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
public static List<KeyValuePair<int, TOutput>> ConvertIndexed<T, TOutput>(this IEnumerable<T> source, Func<T, TOutput> converter, Func<T, int, bool> filter)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (converter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("converter");
|
||
|
}
|
||
|
if (filter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("filter");
|
||
|
}
|
||
|
var index = 0;
|
||
|
var result = new List<KeyValuePair<int, TOutput>>();
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (filter(item, index))
|
||
|
{
|
||
|
result.Add(new KeyValuePair<int, TOutput>(index, converter(item)));
|
||
|
}
|
||
|
index++;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
public static TList ConvertIndexed<T, TOutput, TList>(this IEnumerable<T> source, Func<T, TOutput> converter, Predicate<T> filter)
|
||
|
where TList : ICollection<KeyValuePair<int, TOutput>>, new()
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (converter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("converter");
|
||
|
}
|
||
|
if (filter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("filter");
|
||
|
}
|
||
|
var index = 0;
|
||
|
var result = new TList();
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (filter(item))
|
||
|
{
|
||
|
result.Add(new KeyValuePair<int, TOutput>(index, converter(item)));
|
||
|
}
|
||
|
index++;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
public static TList ConvertIndexed<T, TOutput, TList>(this IEnumerable<T> source, Func<T, TOutput> converter, Func<T, int, bool> filter)
|
||
|
where TList : ICollection<KeyValuePair<int, TOutput>>, new()
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (converter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("converter");
|
||
|
}
|
||
|
if (filter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("filter");
|
||
|
}
|
||
|
var index = 0;
|
||
|
var result = new TList();
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (filter(item, index))
|
||
|
{
|
||
|
result.Add(new KeyValuePair<int, TOutput>(index, converter(item)));
|
||
|
}
|
||
|
index++;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<TOutput> ConvertProgressive<T, TOutput>(this IEnumerable<T> source, Func<T, TOutput> converter)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (converter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("converter");
|
||
|
}
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
yield return converter(item);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<TOutput> ConvertProgressiveFiltered<T, TOutput>(this IEnumerable<T> source, Func<T, TOutput> converter, Predicate<T> filter)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (converter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("converter");
|
||
|
}
|
||
|
if (filter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("filter");
|
||
|
}
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (filter(item))
|
||
|
{
|
||
|
yield return converter(item);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<TOutput> ConvertProgressiveFiltered<T, TOutput>(this IEnumerable<T> source, Func<T, TOutput> converter, Func<T, int, bool> filter)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (converter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("converter");
|
||
|
}
|
||
|
if (filter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("filter");
|
||
|
}
|
||
|
var index = 0;
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (filter(item, index))
|
||
|
{
|
||
|
yield return converter(item);
|
||
|
}
|
||
|
index++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<KeyValuePair<int, TOutput>> ConvertProgressiveIndexed<T, TOutput>(this IEnumerable<T> source, Func<T, TOutput> converter, Predicate<T> filter)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (converter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("converter");
|
||
|
}
|
||
|
if (filter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("filter");
|
||
|
}
|
||
|
var index = 0;
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (filter(item))
|
||
|
{
|
||
|
yield return new KeyValuePair<int, TOutput>(index, converter(item));
|
||
|
}
|
||
|
index++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<KeyValuePair<int, TOutput>> ConvertProgressiveIndexed<T, TOutput>(this IEnumerable<T> source, Func<T, TOutput> converter, Func<T, int, bool> filter)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (converter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("converter");
|
||
|
}
|
||
|
if (filter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("filter");
|
||
|
}
|
||
|
var index = 0;
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (filter(item, index))
|
||
|
{
|
||
|
yield return new KeyValuePair<int, TOutput>(index, converter(item));
|
||
|
}
|
||
|
index++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static T[] Copy<T>(this T[] array)
|
||
|
{
|
||
|
if (array == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("array");
|
||
|
}
|
||
|
// Copyright (c) Microsoft. All rights reserved.
|
||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||
|
var copy = new T[array.Length];
|
||
|
Array.Copy(array, copy, array.Length);
|
||
|
return copy;
|
||
|
}
|
||
|
|
||
|
public static void CopyTo<T>(this IEnumerable<T> source, T[] array)
|
||
|
{
|
||
|
CopyTo(source, array, 0);
|
||
|
}
|
||
|
|
||
|
public static void CopyTo<T>(this IEnumerable<T> source, T[] array, int arrayIndex)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (array == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("array");
|
||
|
}
|
||
|
try
|
||
|
{
|
||
|
var index = arrayIndex;
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
array[index] = item;
|
||
|
index++;
|
||
|
}
|
||
|
}
|
||
|
catch (IndexOutOfRangeException exception)
|
||
|
{
|
||
|
throw new ArgumentException(exception.Message, "array");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void CopyTo<T>(this IEnumerable<T> source, T[] array, int arrayIndex, int countLimit)
|
||
|
{
|
||
|
CopyTo(source.TakeItems(countLimit), array, arrayIndex);
|
||
|
}
|
||
|
|
||
|
public static int CountContiguousItems<T>(this IEnumerable<T> source, T item)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
var result = 0;
|
||
|
var equalityComparer = EqualityComparer<T>.Default;
|
||
|
foreach (var value in source)
|
||
|
{
|
||
|
if (equalityComparer.Equals(value, item))
|
||
|
{
|
||
|
result++;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
public static int CountContiguousItemsWhere<T>(this IEnumerable<T> source, Predicate<T> predicate)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
var result = 0;
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (predicate(item))
|
||
|
{
|
||
|
result++;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
public static int CountItems<T>(this IEnumerable<T> source)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
var result = 0;
|
||
|
foreach (var value in source)
|
||
|
{
|
||
|
result++;
|
||
|
GC.KeepAlive(value);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
public static int CountItems<T>(this IEnumerable<T> source, T item)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
var result = 0;
|
||
|
var equalityComparer = EqualityComparer<T>.Default;
|
||
|
foreach (var value in source)
|
||
|
{
|
||
|
if (equalityComparer.Equals(value, item))
|
||
|
{
|
||
|
result++;
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
public static int CountItemsWhere<T>(this IEnumerable<T> source, Predicate<T> predicate)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
var result = 0;
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (predicate(item))
|
||
|
{
|
||
|
result++;
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
public static void DeprecatedCopyTo<T>(this IEnumerable<T> source, Array array)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (array == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("array");
|
||
|
}
|
||
|
var index = 0;
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
array.SetValue(item, index++);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void DeprecatedCopyTo<T>(this IEnumerable<T> source, Array array, int index)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (array == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("array");
|
||
|
}
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
array.SetValue(item, index++);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<T> EmptyChecked<T>(this IEnumerable<T> source, Action onEmpty)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (onEmpty == null)
|
||
|
{
|
||
|
throw new ArgumentException("onEmpty");
|
||
|
}
|
||
|
var sourceCollection = source as ICollection<T>;
|
||
|
if (sourceCollection != null)
|
||
|
{
|
||
|
if (sourceCollection.Count == 0)
|
||
|
{
|
||
|
onEmpty();
|
||
|
return ArrayReservoir<T>.EmptyArray;
|
||
|
}
|
||
|
}
|
||
|
return NullOrEmptyCheckedExtracted(source, onEmpty);
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<T> EmptyChecked<T>(this IEnumerable<T> source, Action onEmpty, Action onNotEmpty)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (onEmpty == null)
|
||
|
{
|
||
|
throw new ArgumentException("onEmpty");
|
||
|
}
|
||
|
var sourceCollection = source as ICollection<T>;
|
||
|
if (sourceCollection != null)
|
||
|
{
|
||
|
if (sourceCollection.Count == 0)
|
||
|
{
|
||
|
onEmpty();
|
||
|
return ArrayReservoir<T>.EmptyArray;
|
||
|
}
|
||
|
onNotEmpty();
|
||
|
}
|
||
|
return NullOrEmptyCheckedExtracted(source, onEmpty, onNotEmpty);
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<T> EmptyChecked<T>(this IEnumerable<T> source, Action onEmpty, Action onUnknownSize, Action<int> onKnownSize)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (onEmpty == null)
|
||
|
{
|
||
|
throw new ArgumentException("onEmpty");
|
||
|
}
|
||
|
var sourceCollection = source as ICollection<T>;
|
||
|
if (sourceCollection != null)
|
||
|
{
|
||
|
if (sourceCollection.Count == 0)
|
||
|
{
|
||
|
onEmpty();
|
||
|
return ArrayReservoir<T>.EmptyArray;
|
||
|
}
|
||
|
onKnownSize(sourceCollection.Count);
|
||
|
}
|
||
|
return NullOrEmptyCheckedExtracted(source, onEmpty, onUnknownSize);
|
||
|
}
|
||
|
|
||
|
public static int ExceptWith<T>(this ICollection<T> source, IEnumerable<T> other)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (other == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("other");
|
||
|
}
|
||
|
var count = 0;
|
||
|
foreach (var item in other)
|
||
|
{
|
||
|
while (source.Remove(item))
|
||
|
{
|
||
|
count++;
|
||
|
}
|
||
|
}
|
||
|
return count;
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<T> ExceptWithEnumerable<T>(this ICollection<T> source, IEnumerable<T> other)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (other == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("other");
|
||
|
}
|
||
|
foreach (var item in other)
|
||
|
{
|
||
|
while (source.Remove(item))
|
||
|
{
|
||
|
yield return item;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static bool Exists<T>(this IEnumerable<T> source, T value)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
IEqualityComparer<T> comparer = EqualityComparer<T>.Default;
|
||
|
foreach (var local in source)
|
||
|
{
|
||
|
if (comparer.Equals(local, value))
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public static bool Exists<T>(this IEnumerable<T> source, T value, IEqualityComparer<T> comparer)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
comparer = comparer ?? EqualityComparer<T>.Default;
|
||
|
foreach (var local in source)
|
||
|
{
|
||
|
if (comparer.Equals(local, value))
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public static bool Exists<T>(this IEnumerable<T> source, Predicate<T> predicate)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (predicate(item))
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public static T Find<T>(this IEnumerable<T> source, int index, int count, Predicate<T> predicate)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
var limit = index + count;
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
currentIndex++;
|
||
|
if (currentIndex == index)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (currentIndex == limit)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
if (predicate(enumerator.Current))
|
||
|
{
|
||
|
return enumerator.Current;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
return default(T);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static T Find<T>(this IEnumerable<T> source, int index, Predicate<T> predicate)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
currentIndex++;
|
||
|
if (currentIndex == index)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (predicate(enumerator.Current))
|
||
|
{
|
||
|
return enumerator.Current;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
return default(T);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static T Find<T>(this IEnumerable<T> source, Predicate<T> predicate)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (predicate(enumerator.Current))
|
||
|
{
|
||
|
return enumerator.Current;
|
||
|
}
|
||
|
}
|
||
|
return default(T);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static int FindIndex<T>(this IEnumerable<T> source, int index, int count, Predicate<T> predicate)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
var limit = index + count;
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
currentIndex++;
|
||
|
if (currentIndex == index)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (currentIndex == limit)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
if (predicate(enumerator.Current))
|
||
|
{
|
||
|
return currentIndex;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static int FindIndex<T>(this IEnumerable<T> source, Predicate<T> predicate)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (predicate(enumerator.Current))
|
||
|
{
|
||
|
return currentIndex;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static int FindIndex<T>(this IEnumerable<T> source, int index, Predicate<T> predicate)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
currentIndex++;
|
||
|
if (currentIndex == index)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (predicate(enumerator.Current))
|
||
|
{
|
||
|
return currentIndex;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static T FindLast<T>(this IEnumerable<T> source, int index, int count, Predicate<T> predicate)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
var limit = index + count;
|
||
|
var result = default(T);
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
currentIndex++;
|
||
|
if (currentIndex == index)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (currentIndex == limit)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
if (predicate(enumerator.Current))
|
||
|
{
|
||
|
result = enumerator.Current;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static T FindLast<T>(this IEnumerable<T> source, int index, Predicate<T> predicate)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
var result = default(T);
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
currentIndex++;
|
||
|
if (currentIndex == index)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (predicate(enumerator.Current))
|
||
|
{
|
||
|
result = enumerator.Current;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static T FindLast<T>(this IEnumerable<T> source, Predicate<T> predicate)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
var result = default(T);
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (predicate(enumerator.Current))
|
||
|
{
|
||
|
result = enumerator.Current;
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static int FindLastIndex<T>(this IEnumerable<T> source, int index, int count, Predicate<T> predicate)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
var limit = index + count;
|
||
|
var result = -1;
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
currentIndex++;
|
||
|
if (currentIndex == index)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (currentIndex == limit)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
if (predicate(enumerator.Current))
|
||
|
{
|
||
|
result = currentIndex;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static int FindLastIndex<T>(this IEnumerable<T> source, int index, Predicate<T> predicate)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
var result = -1;
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
currentIndex++;
|
||
|
if (currentIndex == index)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (predicate(enumerator.Current))
|
||
|
{
|
||
|
result = currentIndex;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static int FindLastIndex<T>(this IEnumerable<T> source, Predicate<T> predicate)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
var result = -1;
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (predicate(enumerator.Current))
|
||
|
{
|
||
|
result = currentIndex;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static List<T> FindWhere<T>(this IEnumerable<T> source, Predicate<T> predicate)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
var result = new List<T>();
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (predicate(item))
|
||
|
{
|
||
|
result.Add(item);
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
public static TList FindWhere<T, TList>(this IEnumerable<T> source, Predicate<T> predicate)
|
||
|
where TList : ICollection<T>, new()
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
var result = new TList();
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (predicate(item))
|
||
|
{
|
||
|
result.Add(item);
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<T> Flatten<T>(this IEnumerable<IEnumerable<T>> source)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
return FlattenExtracted(source);
|
||
|
}
|
||
|
|
||
|
public static void For<T>(this IEnumerable<T> source, Action<int, T> action)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (action == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("action");
|
||
|
}
|
||
|
var index = 0;
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
action.Invoke(index, item);
|
||
|
index++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void For<T>(this IEnumerable<T> source, Action<int, T> action, Predicate<T> predicate)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
if (action == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("action");
|
||
|
}
|
||
|
var index = 0;
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (predicate.Invoke(item))
|
||
|
{
|
||
|
action.Invoke(index, item);
|
||
|
}
|
||
|
index++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void For<T>(this IEnumerable<T> source, Action<int, T> action, Func<T, int, bool> filter)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (filter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("filter");
|
||
|
}
|
||
|
if (action == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("action");
|
||
|
}
|
||
|
var index = 0;
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (filter.Invoke(item, index))
|
||
|
{
|
||
|
action.Invoke(index, item);
|
||
|
}
|
||
|
index++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (action == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("action");
|
||
|
}
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
action.Invoke(item);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action, Predicate<T> predicate)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
if (action == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("action");
|
||
|
}
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (predicate.Invoke(item))
|
||
|
{
|
||
|
action.Invoke(item);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static TValue GetOrCreate<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
|
||
|
{
|
||
|
if (dictionary == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("dictionary");
|
||
|
}
|
||
|
TValue value;
|
||
|
if (dictionary.TryGetValue(key, out value))
|
||
|
{
|
||
|
return value;
|
||
|
}
|
||
|
var newValue = TypeHelper.CreateOrDefault<TValue>();
|
||
|
dictionary.Add(key, newValue);
|
||
|
return newValue;
|
||
|
}
|
||
|
|
||
|
public static TValue GetOrCreate<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue newValue)
|
||
|
{
|
||
|
if (dictionary == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("dictionary");
|
||
|
}
|
||
|
TValue value;
|
||
|
if (dictionary.TryGetValue(key, out value))
|
||
|
{
|
||
|
return value;
|
||
|
}
|
||
|
dictionary.Add(key, newValue);
|
||
|
return newValue;
|
||
|
}
|
||
|
|
||
|
public static TValue GetOrCreate<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, Func<TValue> create)
|
||
|
{
|
||
|
if (dictionary == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("dictionary");
|
||
|
}
|
||
|
TValue value;
|
||
|
if (dictionary.TryGetValue(key, out value))
|
||
|
{
|
||
|
return value;
|
||
|
}
|
||
|
var newValue = create == null ? default(TValue) : create();
|
||
|
dictionary.Add(key, newValue);
|
||
|
return newValue;
|
||
|
}
|
||
|
|
||
|
public static int IndexOf<T>(this IEnumerable<T> source, T item, int index, int count)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
var limit = index + count;
|
||
|
var comparer = EqualityComparer<T>.Default;
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
currentIndex++;
|
||
|
if (currentIndex == index)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (currentIndex == limit)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
if (comparer.Equals(enumerator.Current, item))
|
||
|
{
|
||
|
return currentIndex;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static int IndexOf<T>(this IEnumerable<T> source, T item, int index, int count, IEqualityComparer<T> comparer)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
var limit = index + count;
|
||
|
comparer = comparer ?? EqualityComparer<T>.Default;
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
currentIndex++;
|
||
|
if (currentIndex == index)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (currentIndex == limit)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
if (comparer.Equals(enumerator.Current, item))
|
||
|
{
|
||
|
return currentIndex;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static int IndexOf<T>(this IEnumerable<T> source, T item, int index)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
var comparer = EqualityComparer<T>.Default;
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
currentIndex++;
|
||
|
if (currentIndex == index)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (comparer.Equals(enumerator.Current, item))
|
||
|
{
|
||
|
return currentIndex;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static int IndexOf<T>(this IEnumerable<T> source, T item, int index, IEqualityComparer<T> comparer)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
comparer = comparer ?? EqualityComparer<T>.Default;
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
currentIndex++;
|
||
|
if (currentIndex == index)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (comparer.Equals(enumerator.Current, item))
|
||
|
{
|
||
|
return currentIndex;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static int IndexOf<T>(this IEnumerable<T> source, T item)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
var comparer = EqualityComparer<T>.Default;
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (comparer.Equals(enumerator.Current, item))
|
||
|
{
|
||
|
return currentIndex;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static int IndexOf<T>(this IEnumerable<T> source, T item, IEqualityComparer<T> comparer)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
comparer = comparer ?? EqualityComparer<T>.Default;
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (comparer.Equals(enumerator.Current, item))
|
||
|
{
|
||
|
return currentIndex;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<T> InterleaveMany<T>(this IEnumerable<IEnumerable<T>> source)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
var enumerators = source.Select(x => x.GetEnumerator()).ToArray();
|
||
|
try
|
||
|
{
|
||
|
var ok = true;
|
||
|
while (ok)
|
||
|
{
|
||
|
ok = false;
|
||
|
foreach (var enumerator in enumerators)
|
||
|
{
|
||
|
if (enumerator.MoveNext())
|
||
|
{
|
||
|
yield return enumerator.Current;
|
||
|
ok = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
finally
|
||
|
{
|
||
|
foreach (var enumerator in enumerators)
|
||
|
{
|
||
|
enumerator.Dispose();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static int IntersectWith<T>(this ICollection<T> source, IEnumerable<T> other)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (other == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("other");
|
||
|
}
|
||
|
var otherAsCollection = AsCollection(other);
|
||
|
return source.RemoveWhere(input => !otherAsCollection.Contains(input));
|
||
|
}
|
||
|
|
||
|
public static int IntersectWith<T>(this ICollection<T> source, IEnumerable<T> other, IEqualityComparer<T> comparer)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (other == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("other");
|
||
|
}
|
||
|
comparer = comparer ?? EqualityComparer<T>.Default;
|
||
|
var otherASCollection = AsCollection(other);
|
||
|
return source.RemoveWhere(input => !otherASCollection.Contains(input, comparer));
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<T> IntersectWithEnumerable<T>(this ICollection<T> source, IEnumerable<T> other)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (other == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("other");
|
||
|
}
|
||
|
var otherAsCollection = AsCollection(other);
|
||
|
return source.RemoveWhereEnumerable(input => !otherAsCollection.Contains(input));
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<T> IntersectWithEnumerable<T>(this ICollection<T> source, IEnumerable<T> other, IEqualityComparer<T> comparer)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (other == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("other");
|
||
|
}
|
||
|
comparer = comparer ?? EqualityComparer<T>.Default;
|
||
|
var otherAsCollection = AsCollection(other);
|
||
|
return source.RemoveWhereEnumerable(input => !otherAsCollection.Contains(input, comparer));
|
||
|
}
|
||
|
|
||
|
public static bool IsEmpty<T>(this IEnumerable<T> source)
|
||
|
{
|
||
|
return !source.Any();
|
||
|
}
|
||
|
|
||
|
public static bool IsProperSubsetOf<T>(this IEnumerable<T> source, IEnumerable<T> other)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (other == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("other");
|
||
|
}
|
||
|
return IsSubsetOf(source, other, true);
|
||
|
}
|
||
|
|
||
|
public static bool IsProperSupersetOf<T>(this IEnumerable<T> source, IEnumerable<T> other)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (other == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("other");
|
||
|
}
|
||
|
return IsSupersetOf(source, other, true);
|
||
|
}
|
||
|
|
||
|
public static bool IsSubsetOf<T>(this IEnumerable<T> source, IEnumerable<T> other)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (other == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("other");
|
||
|
}
|
||
|
return IsSubsetOf(source, other, false);
|
||
|
}
|
||
|
|
||
|
public static bool IsSupersetOf<T>(this IEnumerable<T> source, IEnumerable<T> other)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (other == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("other");
|
||
|
}
|
||
|
return IsSupersetOf(source, other, false);
|
||
|
}
|
||
|
|
||
|
public static int LastIndexOf<T>(this IEnumerable<T> source, T item, int index, IEqualityComparer<T> comparer)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
comparer = comparer ?? EqualityComparer<T>.Default;
|
||
|
var result = -1;
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
currentIndex++;
|
||
|
if (currentIndex == index)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (comparer.Equals(enumerator.Current, item))
|
||
|
{
|
||
|
result = currentIndex;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static int LastIndexOf<T>(this IEnumerable<T> source, T item, int index)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
var comparer = EqualityComparer<T>.Default;
|
||
|
var result = -1;
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
currentIndex++;
|
||
|
if (currentIndex == index)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (comparer.Equals(enumerator.Current, item))
|
||
|
{
|
||
|
result = currentIndex;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static int LastIndexOf<T>(this IEnumerable<T> source, T item)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
var comparer = EqualityComparer<T>.Default;
|
||
|
var result = -1;
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (comparer.Equals(enumerator.Current, item))
|
||
|
{
|
||
|
result = currentIndex;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static int LastIndexOf<T>(this IEnumerable<T> source, T item, IEqualityComparer<T> comparer)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
comparer = comparer ?? EqualityComparer<T>.Default;
|
||
|
var result = -1;
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (comparer.Equals(enumerator.Current, item))
|
||
|
{
|
||
|
result = currentIndex;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static int LastIndexOf<T>(this IEnumerable<T> source, T item, int index, int count, IEqualityComparer<T> comparer)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
var limit = index + count;
|
||
|
comparer = comparer ?? EqualityComparer<T>.Default;
|
||
|
var result = -1;
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
currentIndex++;
|
||
|
if (currentIndex == index)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (currentIndex == limit)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
if (comparer.Equals(enumerator.Current, item))
|
||
|
{
|
||
|
result = currentIndex;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static int LastIndexOf<T>(this IEnumerable<T> source, T item, int index, int count)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
var limit = index + count;
|
||
|
var comparer = EqualityComparer<T>.Default;
|
||
|
var result = -1;
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
currentIndex++;
|
||
|
if (currentIndex == index)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (currentIndex == limit)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
if (comparer.Equals(enumerator.Current, item))
|
||
|
{
|
||
|
result = currentIndex;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static bool ListEquals<T>(this ICollection<T> first, ICollection<T> second)
|
||
|
{
|
||
|
if (first == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("first");
|
||
|
}
|
||
|
if (second == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("second");
|
||
|
}
|
||
|
// Copyright (c) Microsoft. All rights reserved.
|
||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||
|
if (first.Count != second.Count)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
var cmp = EqualityComparer<T>.Default;
|
||
|
var f = first.GetEnumerator();
|
||
|
var s = second.GetEnumerator();
|
||
|
try
|
||
|
{
|
||
|
while (f.MoveNext())
|
||
|
{
|
||
|
s.MoveNext();
|
||
|
|
||
|
if (!cmp.Equals(f.Current, s.Current))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
finally
|
||
|
{
|
||
|
f.Dispose();
|
||
|
s.Dispose();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Name needs to be different so it doesn't conflict with Enumerable.Select
|
||
|
public static TOutput[] Map<TInput, TOutput>(this ICollection<TInput> source, Func<TInput, TOutput> select)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
// Copyright (c) Microsoft. All rights reserved.
|
||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||
|
var count = source.Count;
|
||
|
var result = new TOutput[count];
|
||
|
count = 0;
|
||
|
foreach (var t in source)
|
||
|
{
|
||
|
result[count++] = select(t);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
public static void Move<T>(this IList<T> list, int oldIndex, int newIndex)
|
||
|
{
|
||
|
if (list == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("list");
|
||
|
}
|
||
|
var item = list[oldIndex];
|
||
|
list.RemoveAt(oldIndex);
|
||
|
if (newIndex > oldIndex)
|
||
|
{
|
||
|
newIndex--;
|
||
|
}
|
||
|
list.Insert(newIndex, item);
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<T> NullOrEmptyChecked<T>(this IEnumerable<T> source, Action onEmpty)
|
||
|
{
|
||
|
if (onEmpty == null)
|
||
|
{
|
||
|
throw new ArgumentException("onEmpty");
|
||
|
}
|
||
|
if (source == null)
|
||
|
{
|
||
|
onEmpty();
|
||
|
return ArrayReservoir<T>.EmptyArray;
|
||
|
}
|
||
|
var sourceCollection = source as ICollection<T>;
|
||
|
if (sourceCollection != null)
|
||
|
{
|
||
|
if (sourceCollection.Count == 0)
|
||
|
{
|
||
|
onEmpty();
|
||
|
return ArrayReservoir<T>.EmptyArray;
|
||
|
}
|
||
|
}
|
||
|
return NullOrEmptyCheckedExtracted(source, onEmpty);
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<T> NullOrEmptyChecked<T>(this IEnumerable<T> source, Action onEmpty, Action onNotEmpty)
|
||
|
{
|
||
|
if (onEmpty == null)
|
||
|
{
|
||
|
throw new ArgumentException("onEmpty");
|
||
|
}
|
||
|
if (source == null)
|
||
|
{
|
||
|
onEmpty();
|
||
|
return ArrayReservoir<T>.EmptyArray;
|
||
|
}
|
||
|
var sourceCollection = source as ICollection<T>;
|
||
|
if (sourceCollection != null)
|
||
|
{
|
||
|
if (sourceCollection.Count == 0)
|
||
|
{
|
||
|
onEmpty();
|
||
|
return ArrayReservoir<T>.EmptyArray;
|
||
|
}
|
||
|
onNotEmpty();
|
||
|
}
|
||
|
return NullOrEmptyCheckedExtracted(source, onEmpty, onNotEmpty);
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<T> NullOrEmptyChecked<T>(this IEnumerable<T> source, Action onEmpty, Action onUnknownSize, Action<int> onKnownSize)
|
||
|
{
|
||
|
if (onEmpty == null)
|
||
|
{
|
||
|
throw new ArgumentException("onEmpty");
|
||
|
}
|
||
|
if (source == null)
|
||
|
{
|
||
|
onEmpty();
|
||
|
return ArrayReservoir<T>.EmptyArray;
|
||
|
}
|
||
|
var sourceCollection = source as ICollection<T>;
|
||
|
if (sourceCollection != null)
|
||
|
{
|
||
|
if (sourceCollection.Count == 0)
|
||
|
{
|
||
|
onEmpty();
|
||
|
return ArrayReservoir<T>.EmptyArray;
|
||
|
}
|
||
|
onKnownSize(sourceCollection.Count);
|
||
|
}
|
||
|
return NullOrEmptyCheckedExtracted(source, onEmpty, onUnknownSize);
|
||
|
}
|
||
|
|
||
|
public static bool Overlaps<T>(this IEnumerable<T> source, IEnumerable<T> items)
|
||
|
{
|
||
|
return ContainsAny(source, items);
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<TPackage> Pack<T, TPackage>(this IEnumerable<T> source, int size)
|
||
|
where TPackage : ICollection<T>, new()
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
var count = 0;
|
||
|
var currentPackage = new TPackage();
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
currentPackage.Add(item);
|
||
|
count++;
|
||
|
if (count == size)
|
||
|
{
|
||
|
yield return currentPackage;
|
||
|
currentPackage = new TPackage();
|
||
|
count = 0;
|
||
|
}
|
||
|
}
|
||
|
if (count > 0)
|
||
|
{
|
||
|
yield return currentPackage;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<T[]> Pack<T>(this IEnumerable<T> source, int size)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
var index = 0;
|
||
|
var currentPackage = new T[size];
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
currentPackage[index] = item;
|
||
|
index++;
|
||
|
if (index == size)
|
||
|
{
|
||
|
yield return currentPackage;
|
||
|
currentPackage = new T[size];
|
||
|
index = 0;
|
||
|
}
|
||
|
}
|
||
|
if (index > 0)
|
||
|
{
|
||
|
Array.Resize(ref currentPackage, index);
|
||
|
yield return currentPackage;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static bool Remove<T>(this ICollection<T> source, T item, IEqualityComparer<T> comparer)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
comparer = comparer ?? EqualityComparer<T>.Default;
|
||
|
using (var enumerator = source.RemoveWhereEnumerable(input => comparer.Equals(input, item)).GetEnumerator())
|
||
|
{
|
||
|
return enumerator.MoveNext();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static T[] RemoveFirst<T>(this T[] array)
|
||
|
{
|
||
|
if (array == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("array");
|
||
|
}
|
||
|
// Copyright (c) Microsoft. All rights reserved.
|
||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||
|
var result = new T[array.Length - 1];
|
||
|
Array.Copy(array, 1, result, 0, result.Length);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
public static T[] RemoveLast<T>(this T[] array)
|
||
|
{
|
||
|
if (array == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("array");
|
||
|
}
|
||
|
// Copyright (c) Microsoft. All rights reserved.
|
||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||
|
var result = new T[array.Length - 1];
|
||
|
Array.Copy(array, 0, result, 0, result.Length);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
public static int RemoveWhere<T>(this ICollection<T> source, Predicate<T> predicate)
|
||
|
{
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
return RemoveWhere(source, items => Where(items, predicate));
|
||
|
}
|
||
|
|
||
|
public static int RemoveWhere<T>(this ICollection<T> source, Func<IEnumerable<T>, IEnumerable<T>> converter)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (converter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("converter");
|
||
|
}
|
||
|
return ExceptWith
|
||
|
(
|
||
|
source,
|
||
|
new List<T>(converter.Invoke(source))
|
||
|
);
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<T> RemoveWhereEnumerable<T>(this ICollection<T> source, Predicate<T> predicate)
|
||
|
{
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
return RemoveWhereEnumerable(source, items => Where(items, predicate));
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<T> RemoveWhereEnumerable<T>(this ICollection<T> source, Func<IEnumerable<T>, IEnumerable<T>> converter)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (converter == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("converter");
|
||
|
}
|
||
|
return ExceptWithEnumerable
|
||
|
(
|
||
|
source,
|
||
|
new List<T>(converter.Invoke(source))
|
||
|
);
|
||
|
}
|
||
|
|
||
|
public static void Reverse<T>(this IList<T> list, int index, int count)
|
||
|
{
|
||
|
if (list == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("list");
|
||
|
}
|
||
|
if (index < 0)
|
||
|
{
|
||
|
throw new ArgumentOutOfRangeException("index", "Non-negative number is required.");
|
||
|
}
|
||
|
if (count < 0)
|
||
|
{
|
||
|
throw new ArgumentOutOfRangeException("count", "Non-negative number is required.");
|
||
|
}
|
||
|
var listCount = list.Count;
|
||
|
if (count > listCount - index)
|
||
|
{
|
||
|
throw new ArgumentException("The list does not contain the number of elements.", "list");
|
||
|
}
|
||
|
var end = index + count;
|
||
|
for (; index < end; index++, end++)
|
||
|
{
|
||
|
SwapExtracted(list, index, end);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static bool SetEquals<T>(this ICollection<T> source, IEnumerable<T> other)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (other == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("other");
|
||
|
}
|
||
|
var thatAsCollection = AsCollection(other);
|
||
|
foreach (var item in thatAsCollection.Where(input => !source.Contains(input)))
|
||
|
{
|
||
|
GC.KeepAlive(item);
|
||
|
return false;
|
||
|
}
|
||
|
foreach (var item in source.Where(input => !thatAsCollection.Contains(input)))
|
||
|
{
|
||
|
GC.KeepAlive(item);
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
public static void Sort<T>(this IList<T> list, int index, int count, IComparer<T> comparer)
|
||
|
{
|
||
|
if (list == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("list");
|
||
|
}
|
||
|
comparer = comparer ?? Comparer<T>.Default;
|
||
|
if (index < 0)
|
||
|
{
|
||
|
throw new ArgumentOutOfRangeException("index", "Non-negative number is required.");
|
||
|
}
|
||
|
if (count < 0)
|
||
|
{
|
||
|
throw new ArgumentOutOfRangeException("count", "Non-negative number is required.");
|
||
|
}
|
||
|
var listCount = list.Count;
|
||
|
if (count > listCount - index)
|
||
|
{
|
||
|
throw new ArgumentException("The list does not contain the number of elements.", "list");
|
||
|
}
|
||
|
SortExtracted(list, index, count + index, comparer);
|
||
|
}
|
||
|
|
||
|
public static void Swap<T>(this IList<T> list, int indexA, int indexB)
|
||
|
{
|
||
|
if (list == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("list");
|
||
|
}
|
||
|
if (indexA < 0)
|
||
|
{
|
||
|
throw new ArgumentOutOfRangeException("indexA", "Non-negative number is required.");
|
||
|
}
|
||
|
if (indexB < 0)
|
||
|
{
|
||
|
throw new ArgumentOutOfRangeException("indexB", "Non-negative number is required.");
|
||
|
}
|
||
|
var listCount = list.Count;
|
||
|
if (indexA >= listCount || indexB >= listCount)
|
||
|
{
|
||
|
throw new ArgumentException("The list does not contain the number of elements.", "list");
|
||
|
}
|
||
|
if (indexA != indexB)
|
||
|
{
|
||
|
SwapExtracted(list, indexA, indexB);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static int SymmetricExceptWith<T>(this ICollection<T> source, IEnumerable<T> other)
|
||
|
{
|
||
|
return source.AddRange(Where(other.Distinct(), input => !source.Remove(input)));
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<T> SymmetricExceptWithEnumerable<T>(this ICollection<T> source, IEnumerable<T> other)
|
||
|
{
|
||
|
return source.AddRangeEnumerable(Where(other.Distinct(), input => !source.Remove(input)));
|
||
|
}
|
||
|
|
||
|
public static T[] ToArray<T>(this ICollection<T> source)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
return (new List<T>(source)).ToArray();
|
||
|
}
|
||
|
|
||
|
public static ReadOnlyCollection<TSource> ToReadOnly<TSource>(this IEnumerable<TSource> source)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
return new ReadOnlyCollection<TSource>(ArrayReservoir<TSource>.EmptyArray);
|
||
|
}
|
||
|
var sourceAsReadOnlyCollection = source as ReadOnlyCollection<TSource>;
|
||
|
if (sourceAsReadOnlyCollection != null)
|
||
|
{
|
||
|
return sourceAsReadOnlyCollection;
|
||
|
}
|
||
|
return new ReadOnlyCollection<TSource>(source.ToArray());
|
||
|
}
|
||
|
|
||
|
public static bool TryAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue value)
|
||
|
{
|
||
|
if (dictionary == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("dictionary");
|
||
|
}
|
||
|
try
|
||
|
{
|
||
|
dictionary.Add(key, value);
|
||
|
return true;
|
||
|
}
|
||
|
catch (ArgumentException ex)
|
||
|
{
|
||
|
GC.KeepAlive(ex);
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static bool TryFind<T>(this IEnumerable<T> source, int index, int count, Predicate<T> predicate, out T founT)
|
||
|
{
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
var limit = index + count;
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
currentIndex++;
|
||
|
if (currentIndex == index)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (currentIndex == limit)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
if (predicate(enumerator.Current))
|
||
|
{
|
||
|
founT = enumerator.Current;
|
||
|
return true;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
founT = default(T);
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static bool TryFind<T>(this IEnumerable<T> source, int index, Predicate<T> predicate, out T founT)
|
||
|
{
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
currentIndex++;
|
||
|
if (currentIndex == index)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (predicate(enumerator.Current))
|
||
|
{
|
||
|
founT = enumerator.Current;
|
||
|
return true;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
founT = default(T);
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static bool TryFind<T>(this IEnumerable<T> source, Predicate<T> predicate, out T founT)
|
||
|
{
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (predicate(enumerator.Current))
|
||
|
{
|
||
|
founT = enumerator.Current;
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
founT = default(T);
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static bool TryFindLast<T>(this IEnumerable<T> source, int index, int count, Predicate<T> predicate, out T foundItem)
|
||
|
{
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
var limit = index + count;
|
||
|
foundItem = default(T);
|
||
|
var found = false;
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
currentIndex++;
|
||
|
if (currentIndex == index)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (currentIndex == limit)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
if (predicate(enumerator.Current))
|
||
|
{
|
||
|
foundItem = enumerator.Current;
|
||
|
found = true;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
return found;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static bool TryFindLast<T>(this IEnumerable<T> source, int index, Predicate<T> predicate, out T foundItem)
|
||
|
{
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
var currentIndex = 0;
|
||
|
foundItem = default(T);
|
||
|
var found = false;
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
currentIndex++;
|
||
|
if (currentIndex == index)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (predicate(enumerator.Current))
|
||
|
{
|
||
|
foundItem = enumerator.Current;
|
||
|
found = true;
|
||
|
}
|
||
|
currentIndex++;
|
||
|
}
|
||
|
return found;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static bool TryFindLast<T>(this IEnumerable<T> source, Predicate<T> predicate, out T foundItem)
|
||
|
{
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
foundItem = default(T);
|
||
|
var found = false;
|
||
|
using (var enumerator = source.GetEnumerator())
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
if (predicate(enumerator.Current))
|
||
|
{
|
||
|
foundItem = enumerator.Current;
|
||
|
found = true;
|
||
|
}
|
||
|
}
|
||
|
return found;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static bool TryTake<T>(this Stack<T> stack, out T item)
|
||
|
{
|
||
|
if (stack == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("stack");
|
||
|
}
|
||
|
try
|
||
|
{
|
||
|
item = stack.Pop();
|
||
|
return true;
|
||
|
}
|
||
|
catch (InvalidOperationException)
|
||
|
{
|
||
|
item = default(T);
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static bool TryTake<T>(this Queue<T> queue, out T item)
|
||
|
{
|
||
|
if (queue == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("queue");
|
||
|
}
|
||
|
try
|
||
|
{
|
||
|
item = queue.Dequeue();
|
||
|
return true;
|
||
|
}
|
||
|
catch (InvalidOperationException)
|
||
|
{
|
||
|
item = default(T);
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static int UnionWith<T>(this ICollection<T> source, IEnumerable<T> other)
|
||
|
{
|
||
|
return source.AddRange(other.Where(input => !source.Contains(input)));
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<T> UnionWithEnumerable<T>(this ICollection<T> source, IEnumerable<T> other)
|
||
|
{
|
||
|
return source.AddRangeEnumerable(other.Where(input => !source.Contains(input)));
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<T> Where<T>(IEnumerable<T> source, Predicate<T> predicate)
|
||
|
{
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
return WhereExtracted(source, predicate);
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T, int, bool> predicate)
|
||
|
{
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
return WhereExtracted(source, predicate);
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T, bool> predicate, Action whereNot)
|
||
|
{
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (whereNot == null)
|
||
|
{
|
||
|
return WhereExtracted(source, predicate);
|
||
|
}
|
||
|
return WhereExtracted(source, predicate, whereNot);
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T, bool> predicate, Action<T> whereNot)
|
||
|
{
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (whereNot == null)
|
||
|
{
|
||
|
return WhereExtracted(source, predicate);
|
||
|
}
|
||
|
return WhereExtracted(source, predicate, whereNot);
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T, int, bool> predicate, Action whereNot)
|
||
|
{
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (whereNot == null)
|
||
|
{
|
||
|
return WhereExtracted(source, predicate);
|
||
|
}
|
||
|
return WhereExtracted(source, predicate, whereNot);
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T, int, bool> predicate, Action<T> whereNot)
|
||
|
{
|
||
|
if (predicate == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("predicate");
|
||
|
}
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (whereNot == null)
|
||
|
{
|
||
|
return WhereExtracted(source, predicate);
|
||
|
}
|
||
|
return WhereExtracted(source, predicate, whereNot);
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<T> WhereType<T>(IEnumerable enumerable)
|
||
|
{
|
||
|
return new EnumerableFromDelegate<T>(enumerable.GetEnumerator);
|
||
|
}
|
||
|
|
||
|
public static IEnumerable<TResult> ZipMany<T, TResult>(this IEnumerable<IEnumerable<T>> source, Func<IEnumerable<T>, TResult> func)
|
||
|
{
|
||
|
var enumerators = source.Select(x => x.GetEnumerator()).ToArray();
|
||
|
try
|
||
|
{
|
||
|
while (enumerators.All(enumerator => enumerator.MoveNext()))
|
||
|
{
|
||
|
yield return func(enumerators.Select(enumerator => enumerator.Current));
|
||
|
}
|
||
|
}
|
||
|
finally
|
||
|
{
|
||
|
foreach (var enumerator in enumerators)
|
||
|
{
|
||
|
enumerator.Dispose();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static IEnumerable<T> FlattenExtracted<T>(IEnumerable<IEnumerable<T>> source)
|
||
|
{
|
||
|
foreach (var key in source)
|
||
|
{
|
||
|
foreach (var item in key)
|
||
|
{
|
||
|
yield return item;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static bool IsSubsetOf<T>(this IEnumerable<T> source, IEnumerable<T> other, bool proper)
|
||
|
{
|
||
|
var @this = AsDistinctCollection(source);
|
||
|
var that = AsDistinctCollection(other);
|
||
|
var elementCount = 0;
|
||
|
var matchCount = 0;
|
||
|
foreach (var item in that)
|
||
|
{
|
||
|
elementCount++;
|
||
|
if (@this.Contains(item))
|
||
|
{
|
||
|
matchCount++;
|
||
|
}
|
||
|
}
|
||
|
if (proper)
|
||
|
{
|
||
|
return matchCount == @this.Count && elementCount > @this.Count;
|
||
|
}
|
||
|
return matchCount == @this.Count;
|
||
|
}
|
||
|
|
||
|
private static bool IsSupersetOf<T>(this IEnumerable<T> source, IEnumerable<T> other, bool proper)
|
||
|
{
|
||
|
var @this = AsDistinctCollection(source);
|
||
|
var that = AsDistinctCollection(other);
|
||
|
var elementCount = 0;
|
||
|
foreach (var item in that)
|
||
|
{
|
||
|
elementCount++;
|
||
|
if (!@this.Contains(item))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
if (proper)
|
||
|
{
|
||
|
return elementCount < @this.Count;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
private static IEnumerable<T> NullOrEmptyCheckedExtracted<T>(IEnumerable<T> source, Action onEmpty)
|
||
|
{
|
||
|
var enumerator = source.GetEnumerator();
|
||
|
try
|
||
|
{
|
||
|
if (enumerator.MoveNext())
|
||
|
{
|
||
|
yield return enumerator.Current;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
onEmpty();
|
||
|
yield break;
|
||
|
}
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
yield return enumerator.Current;
|
||
|
}
|
||
|
}
|
||
|
finally
|
||
|
{
|
||
|
enumerator.Dispose();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static IEnumerable<T> NullOrEmptyCheckedExtracted<T>(IEnumerable<T> source, Action onEmpty, Action onNotEmpty)
|
||
|
{
|
||
|
var enumerator = source.GetEnumerator();
|
||
|
try
|
||
|
{
|
||
|
if (enumerator.MoveNext())
|
||
|
{
|
||
|
onNotEmpty();
|
||
|
yield return enumerator.Current;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
onEmpty();
|
||
|
yield break;
|
||
|
}
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
yield return enumerator.Current;
|
||
|
}
|
||
|
}
|
||
|
finally
|
||
|
{
|
||
|
enumerator.Dispose();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static void SortExtracted<T>(IList<T> list, int indexStart, int indexEnd, IComparer<T> comparer)
|
||
|
{
|
||
|
var low = indexStart;
|
||
|
var high = indexEnd;
|
||
|
var pivot = list[low + ((high - low) / 2)];
|
||
|
while (low <= high)
|
||
|
{
|
||
|
while (low < indexEnd && comparer.Compare(list[low], pivot) < 0)
|
||
|
{
|
||
|
low++;
|
||
|
}
|
||
|
while (high > indexStart && comparer.Compare(pivot, list[high]) < 0)
|
||
|
{
|
||
|
high--;
|
||
|
}
|
||
|
if (low == high)
|
||
|
{
|
||
|
low++;
|
||
|
high--;
|
||
|
}
|
||
|
else if (low < high)
|
||
|
{
|
||
|
SwapExtracted(list, low, high);
|
||
|
low++;
|
||
|
high--;
|
||
|
}
|
||
|
}
|
||
|
if (indexStart < high)
|
||
|
{
|
||
|
SortExtracted(list, indexStart, high, comparer);
|
||
|
}
|
||
|
if (low < indexEnd)
|
||
|
{
|
||
|
SortExtracted(list, low, indexEnd, comparer);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static void SwapExtracted<T>(IList<T> list, int indexA, int indexB)
|
||
|
{
|
||
|
var itemA = list[indexA];
|
||
|
var itemB = list[indexB];
|
||
|
list[indexA] = itemB;
|
||
|
list[indexB] = itemA;
|
||
|
}
|
||
|
|
||
|
private static IEnumerable<T> WhereExtracted<T>(IEnumerable<T> source, Predicate<T> predicate)
|
||
|
{
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (predicate(item))
|
||
|
{
|
||
|
yield return item;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static IEnumerable<T> WhereExtracted<T>(IEnumerable<T> source, Func<T, int, bool> predicate)
|
||
|
{
|
||
|
var index = 0;
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (predicate(item, index))
|
||
|
{
|
||
|
yield return item;
|
||
|
}
|
||
|
index++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static IEnumerable<T> WhereExtracted<T>(IEnumerable<T> source, Func<T, bool> predicate, Action whereNot)
|
||
|
{
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (predicate(item))
|
||
|
{
|
||
|
yield return item;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
whereNot();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static IEnumerable<T> WhereExtracted<T>(IEnumerable<T> source, Func<T, bool> predicate)
|
||
|
{
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (predicate(item))
|
||
|
{
|
||
|
yield return item;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static IEnumerable<T> WhereExtracted<T>(IEnumerable<T> source, Func<T, int, bool> predicate, Action whereNot)
|
||
|
{
|
||
|
var index = 0;
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (predicate(item, index))
|
||
|
{
|
||
|
yield return item;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
whereNot();
|
||
|
}
|
||
|
index++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static IEnumerable<T> WhereExtracted<T>(IEnumerable<T> source, Func<T, bool> predicate, Action<T> whereNot)
|
||
|
{
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (predicate(item))
|
||
|
{
|
||
|
yield return item;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
whereNot(item);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static IEnumerable<T> WhereExtracted<T>(IEnumerable<T> source, Func<T, int, bool> predicate, Action<T> whereNot)
|
||
|
{
|
||
|
var index = 0;
|
||
|
foreach (var item in source)
|
||
|
{
|
||
|
if (predicate(item, index))
|
||
|
{
|
||
|
yield return item;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
whereNot(item);
|
||
|
}
|
||
|
index++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal static partial class Extensions
|
||
|
{
|
||
|
#if NET35 || !NET_4_6
|
||
|
|
||
|
public static bool Contains<T>(this IEnumerable<T> source, IEnumerable<T> items)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (items == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("items");
|
||
|
}
|
||
|
var localComparer = EqualityComparer<T>.Default;
|
||
|
var localCollection = AsCollection(source);
|
||
|
foreach (var item in items)
|
||
|
{
|
||
|
if (!localCollection.Contains(item, localComparer))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
public static bool Contains<T>(this IEnumerable<T> source, IEnumerable<T> items, IEqualityComparer<T> comparer)
|
||
|
{
|
||
|
if (source == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("source");
|
||
|
}
|
||
|
if (items == null)
|
||
|
{
|
||
|
throw new ArgumentNullException("items");
|
||
|
}
|
||
|
var localComparer = comparer ?? EqualityComparer<T>.Default;
|
||
|
var localCollection = AsCollection(source);
|
||
|
foreach (var item in items)
|
||
|
{
|
||
|
if (!localCollection.Contains(item, localComparer))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
#endif
|