7

在 C# 中,调用该.Split方法会根据某个字符或字符串将字符串拆分为字符串数组。

列表或数组是否有等效的方法?

例如:

var foo = new List<int>() { 1, 2, 3, 0, 4, 5, 0, 6 };
var output = Split(foo, 0);
// produces { { 1, 2, 3 }, { 4, 5 }, { 6 } }

到目前为止,这就是我所拥有的——有没有一种更简洁或更雄辩的方式来完成同样的任务?

IEnumerable<IEnumerable<T>> Split<T>(IEnumerable<T> list, T divider)
{
    var output = new List<List<T>>();
    var temp = new List<T>();
    foreach ( var item in list )
    {
        if (item.Equals(divider))
        {
            output.Add(temp);
            temp = new List<T>();
        }
        else
        {
            temp.Add(item);
        }
    }

    output.Add(temp);
    return output;
}

编辑:

我突然想到我的版本将仅按单个元素拆分列表,而string.Split可以使用单个字符或任意字符串进行拆分。

只是为了完整起见,实现它的最佳方法是什么?

4

3 回答 3

8

没有内置的等价物,但懒惰评估的会是

IEnumerable<IEnumerable<T>> Split<T>(IEnumerable<T> list, T divider)
{
    var temp = new List<T>();
    foreach (var item in list)
    {
        if (!item.Equals(divider))
        {
            temp.Add(item);
        }
        else
        {
            yield return temp;
            temp = new List<T>();
        }
    }

    if(temp.Count>0) yield return temp;
}
于 2013-07-18T22:43:07.540 回答
2

不,框架中没有特殊的现有方法来拆分序列。

你的代码是合理的。

改进/改变的途径:

  • 您可以使用yield return而不是添加来output获得一些惰性评估。
  • 使用更有趣的代码,您也可以使内部列表变得惰性(如果传入的序列未绑定/太长的段,这可能很重要)。
  • Aggregate如果你想炫耀单个语句代码,你可以使用......
于 2013-07-18T22:48:11.360 回答
0

不知道任何内置功能。但是,我会考虑这样做:

public static IEnumerable<List<int>> Split(List<int> list, int delimiter)
{
    var start = 0;
    foreach (var end in list.FindAll(x => x == delimiter).Select(splitter => list.IndexOf(splitter, start)))
    {
        yield return list.GetRange(start, end - start);

        start = end + 1;
    }

    if (start <= list.Count)
    {
        yield return list.GetRange(start, list.Count - start);
    }
}
于 2013-07-18T23:23:14.737 回答