linq 使用值作为分隔符将列表拆分为子列表

qxsslcnc  于 2022-12-06  发布在  其他
关注(0)|答案(2)|浏览(191)

几乎每一种编程语言都有一个字符串拆分函数:

foreach (var partition in "12304508".Split("0"))
{
    Console.WriteLine(partition);
}
// Output:
// 123
// 45
// 8

有没有什么方法可以做同样的事情,但对于一个通用的列表,而不是一个字符串,即类似于:

int[] nums = new int[] {1, 2, 3, 0, 4, 5, 0, 8}; // can be any generic type instead of int
foreach (var partition in nums.SomeLinqFunctionHere(0))
{
    Console.WriteLine(partition);
}
// Expected output:
// int[]{1, 2, 3}
// int[]{4, 5}
// int[]{8}

最简单的方法是什么?

voj3qocg

voj3qocg1#

请尝试以下操作:

public static class EnumerableExtensions
{
    public static IEnumerable<T[]> SplitEnumerable<T>(this IEnumerable<T> enumerable, T byValue)
    {
        return SplitEnumerable(enumerable, byValue, EqualityComparer<T>.Default);
    }

    public static IEnumerable<T[]> SplitEnumerable<T>(this IEnumerable<T> enumerable, T byValue, IEqualityComparer<T> comparer)
    {
        List<T> buffer = new List<T>();
        foreach (var v in enumerable)
        {
            if (comparer.Equals(v, byValue))
            {
                yield return buffer.ToArray();
                buffer.Clear();
            }
            else
            {
                buffer.Add(v);
            }
        }

        yield return buffer.ToArray();
    }
}
2nc8po8w

2nc8po8w2#

这应该可以工作,而且在某种程度上是灵活的,您可以按条件而不是仅按值进行拆分:

public static IEnumerable<IList<T>> SplitBy<T>(this IEnumerable<T> sequence, Predicate<T> matchFilter)
{
    List<T> list = new List<T>();
    foreach(T item in sequence)
    {
        if (matchFilter(item))
        {
            yield return list;
            list = new List<T>();
        }
        else
        {
            list.Add(item);
        }
    }
    if (list.Any()) yield return list;
}

用途:

int[] nums = new int[] { 1, 2, 3, 0, 4, 5, 0, 8 }; // can be any generic type instead of int
foreach (var partition in nums.SplitBy(i => i == 0))
{
     Console.WriteLine(String.Join(",", partition));
}

相关问题