Какой ваш любимый оператор LINQ to Objects, который не является встроенным? - PullRequest
73 голосов
/ 05 сентября 2010

С помощью методов расширения мы можем написать удобные операторы LINQ, которые решают общие проблемы.

Я хочу услышать, какие методы или перегрузки отсутствуют в пространстве имен System.Linq и как вы их реализовали.

Предпочтительны чистые и элегантные реализации, возможно, с использованием существующих методов.

Ответы [ 43 ]

0 голосов
/ 06 сентября 2010

WhereLike

Объединяет Where с SQL LIKE сопоставлением с образцом.

public static IEnumerable<TSource> WhereLike<TSource>(this IEnumerable<TSource> source, Func<TSource, string> selector, string match)
    {
        /* Turn "off" all regular expression related syntax in
            * the pattern string. */
        string pattern = Regex.Escape(match);

        /* Replace the SQL LIKE wildcard metacharacters with the
        * equivalent regular expression metacharacters. */
        pattern = pattern.Replace("%", ".*?").Replace("_", ".");

        /* The previous call to Regex.Escape actually turned off
        * too many metacharacters, i.e. those which are recognized by
        * both the regular expression engine and the SQL LIKE
        * statement ([...] and [^...]). Those metacharacters have
        * to be manually unescaped here. */
        pattern = pattern.Replace(@"\[", "[").Replace(@"\]", "]").Replace(@"\^", "^");
        Regex reg = new Regex(pattern, RegexOptions.IgnoreCase);

        return source.Where(t => reg.IsMatch(selector(t)));
    }
0 голосов
/ 06 сентября 2010
public static IEnumerable<T> Append<T>(this IEnumerable<T> enumerable, T item)
{
 return enumerable.Concat(new[] { item });
}

public static IEnumerable<T> AppendIf<T>(this IEnumerable<T> enumerable, T item, Func<bool> predicate)
{
 return predicate() ? enumerable.Append(item) : enumerable;
}
0 голосов
/ 06 сентября 2010

Между

C # эквивалентом общеизвестной SQL-конструкции «между»

/// <summary>
/// Determines if the current value is included in the range of specified values. Bounds are included.
/// </summary>
/// <typeparam name="T">The type of the values</typeparam>
/// <param name="val">The value.</param>
/// <param name="firstValue">The lower bound.</param>
/// <param name="secondValue">The upper bound.</param>
/// <returns>
/// Return <c>true</c> if the <paramref name="val">value</paramref> is between the <paramref name="firstValue"/> and the <paramref name="secondValue"/>; otherwise, <c>false</c>
/// </returns>
public static bool Between<T>(this T val, T firstValue, T secondValue) where T : IComparable<T>
{
  if (val == null)
    throw new ArgumentNullException();

  if (firstValue == null ||
      secondValue == null)
    return false;

  return firstValue.CompareTo(val) <= 0 && secondValue.CompareTo(val) >= 0;
}
...