What's your favorite LINQ to Objects operator

2019-01-12 14:19发布

With extension methods, we can write handy LINQ operators which solve generic problems.

I want to hear which methods or overloads you are missing in the System.Linq namespace and how you implemented them.

Clean and elegant implementations, maybe using existing methods, are preferred.

30条回答
疯言疯语
2楼-- · 2019-01-12 14:45

ToQueue & ToStack

/// <summary>Creates a <see cref="Queue&lt;T&gt;"/> from an enumerable
/// collection.</summary>
public static Queue<T> ToQueue<T>(this IEnumerable<T> source)
{
    if (source == null)
        throw new ArgumentNullException("source");
    return new Queue<T>(source);
}

/// <summary>Creates a <see cref="Stack&lt;T&gt;"/> from an enumerable
/// collection.</summary>
public static Stack<T> ToStack<T>(this IEnumerable<T> source)
{
    if (source == null)
        throw new ArgumentNullException("source");
    return new Stack<T>(source);
}
查看更多
ゆ 、 Hurt°
3楼-- · 2019-01-12 14:48

Duplicates

Used in conjunction with a method like Ani's AssertCount method (I use one called CountAtLeast), it becomes very easy to find elements in a sequence that appear more than once:

public static IEnumerable<T> Duplicates<T, TKey>(this IEnumerable<T> source,
    Func<T, TKey> keySelector = null, IEqualityComparer<TKey> comparer = null)
{
    source.ThrowIfNull("source");
    keySelector = keySelector ?? new Func<T, TKey>(x => x);
    comparer = comparer ?? EqualityComparer<TKey>.Default;

    return source.GroupBy(keySelector, comparer)
        .Where(g => g.CountAtLeast(2))
        .SelectMany(g => g);
}
查看更多
啃猪蹄的小仙女
4楼-- · 2019-01-12 14:49

RandomSample

Here's a simple function that's useful if you have a medium-large set of data (say, over 100 items) and you want to eyeball just a random sampling of it.

public static IEnumerable<T> RandomSample<T>(this IEnumerable<T> source,
                                             double percentage)
{
    source.ThrowIfNull("source");

    var r = new Random();
    return source.Where(x => (r.NextDouble() * 100.0) < percentage);
}

Usage:

List<DataPoint> data = GetData();

// Sample roughly 3% of the data
var sample = data.RandomSample(3.0);

// Verify results were correct for this sample
foreach (DataPoint point in sample)
{
    Console.WriteLine("{0} => {1}", point, DoCalculation(point));
}

Notes:

  1. Not really appropriate for tiny collections as the number of items returned is probabilistic (could easily return zero on a small sequence).
  2. Not really appropriate for huge collections or database queries as it involves enumerating over every item in the sequence.
查看更多
叼着烟拽天下
5楼-- · 2019-01-12 14:50

JoinString

Basically the same as string.Join, but:

  • with the ability to use it on any collection, not just a collection of strings (calls ToString on every element)

  • with the ability to add a prefix and suffix to every string.

  • as an extension method. I find string.Join annoying because it is static, meaning that in a chain of operations it is lexically not in the correct order.


/// <summary>
/// Turns all elements in the enumerable to strings and joins them using the
/// specified string as the separator and the specified prefix and suffix for
/// each string.
/// <example>
///   <code>
///     var a = (new[] { "Paris", "London", "Tokyo" }).JoinString(", ", "[", "]");
///     // a contains "[Paris], [London], [Tokyo]"
///   </code>
/// </example>
/// </summary>
public static string JoinString<T>(this IEnumerable<T> values,
    string separator = null, string prefix = null, string suffix = null)
{
    if (values == null)
        throw new ArgumentNullException("values");

    using (var enumerator = values.GetEnumerator())
    {
        if (!enumerator.MoveNext())
            return "";
        StringBuilder sb = new StringBuilder();
        sb.Append(prefix).Append(enumerator.Current.ToString()).Append(suffix);
        while (enumerator.MoveNext())
            sb.Append(separator).Append(prefix)
              .Append(enumerator.Current.ToString()).Append(suffix);
        return sb.ToString();
    }
}
查看更多
对你真心纯属浪费
6楼-- · 2019-01-12 14:50

Chunks

Returns chunks of a specific size. x.Chunks(2) of 1,2,3,4,5 will return two arrays with 1,2 and 3,4. x.Chunks(2,true) will return 1,2, 3,4 and 5.

public static IEnumerable<T[]> Chunks<T>(this IEnumerable<T> xs, int size, bool returnRest = false)
{
    var curr = new T[size];

    int i = 0;

    foreach (var x in xs)
    {
        if (i == size)
        {
            yield return curr;
            i = 0;
            curr = new T[size];
        }

        curr[i++] = x;
    }

    if (returnRest)
        yield return curr.Take(i).ToArray();
}
查看更多
姐就是有狂的资本
7楼-- · 2019-01-12 14:50

ToHashSet

public static HashSet<T> ToHashSet<T>(this IEnumerable<T> items)
{
    return new HashSet<T>(items);
}
查看更多
登录 后发表回答