Skip to content

Instantly share code, notes, and snippets.

@lavn0
Last active March 23, 2017 12:34
Show Gist options
  • Save lavn0/299fb3cf09b57fa8ee86c3ef174aa49d to your computer and use it in GitHub Desktop.
Save lavn0/299fb3cf09b57fa8ee86c3ef174aa49d to your computer and use it in GitHub Desktop.
using System.Collections.Generic;
using System.Diagnostics;
namespace System.Linq
{
/// <summary>LINQ Extension</summary>
[DebuggerStepThrough]
public static partial class LINQX
{
public static bool? MixedResult<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
bool? result = null;
foreach (var item in source)
{
var ret = predicate(item);
if (result.HasValue && result == ret)
{
return null;
}
result = ret;
}
return result;
}
/// <summary>指定した個数以上か評価します</summary>
public static bool CountOver<TSource>(this IEnumerable<TSource> source, int overCount)
{
return source.ElementAtOrDefault(overCount) != null;
}
/// <summary>指定した個数以上か評価します</summary>
public static bool CountOver<TSource>(this IEnumerable<TSource> source, int overCount, Func<TSource, bool> predicate)
{
return source.Where(predicate).ElementAtOrDefault(overCount) != null;
}
/// <summary>指定した個数以下か評価します</summary>
public static bool CountUnder<TSource>(this IEnumerable<TSource> source, int underCount)
{
return underCount <= 1 ? false : source.ElementAtOrDefault(underCount - 1) == null;
}
/// <summary>指定した個数以下か評価します</summary>
public static bool CountUnder<TSource>(this IEnumerable<TSource> source, int underCount, Func<TSource, bool> predicate)
{
return underCount <= 1 ? false : source.Where(predicate).ElementAtOrDefault(underCount - 1) == null;
}
/// <summary>指定した個数かどうか評価します</summary>
public static bool CountEquals<TSource>(this IEnumerable<TSource> source, int count)
{
if (count == 0)
{
return !source.Any();
}
var result = source;
if (count - 1 > 0)
{
result = source.Skip(count - 1);
}
return result.Take(2).Count() == 1;
}
/// <summary>指定した個数かどうか評価します</summary>
public static bool CountEquals<TSource>(this IEnumerable<TSource> source, int count, Func<TSource, bool> predicate)
{
if (count == 0)
{
return !source.Where(predicate).Any();
}
var result = source.Where(predicate);
if (count - 1 > 0)
{
result = source.Skip(count - 1);
}
return result.Take(2).Count() == 1;
}
/// <summary>シーケンスの最後から、指定された数の連続する要素を返します。</summary>
public static IEnumerable<TSource> TakeLast<TSource>(this IEnumerable<TSource> source, int count)
{
return source.Reverse().Take(count).Reverse();
}
/// <summary>子孫要素を再帰的に返します。</summary>
/// <typeparam name="T">型</typeparam>
/// <param name="source">子要素を持つインスタンス</param>
/// <param name="getChildren">子要素を評価する式</param>
/// <returns>子孫要素</returns>
public static IEnumerable<T> GetDescendants<T>(this T source, Func<T, IEnumerable<T>> getChildren)
{
if (source != null)
{
var children = getChildren(source);
if (children != null)
{
foreach (var child in children)
{
yield return child;
var grandChildren = child.GetDescendants(getChildren);
if (grandChildren != null)
{
foreach (var grandChild in grandChildren)
{
yield return grandChild;
}
}
}
}
}
}
public static IEnumerable<T> Seek<T>(T seed, Func<T, T> iterator)
{
for (T item = seed; item != null; item = iterator(item))
{
yield return item;
}
}
public static IEnumerable<T> Seek<T>(T seed, Func<T, T> iterator, Func<T, bool> continues)
{
for (T item = seed; item != null; item = iterator(item))
{
yield return item;
if (!continues(item))
{
break;
}
}
}
public static IEnumerable<T> TakeUntil<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{
foreach (var item in source)
{
yield return item;
if (!predicate(item))
{
break;
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment