我爲此寫了一個擴展方法,可以在任何IEnumerable<T>
上使用。
/// <summary>
/// Splits the specified IEnumerable at every element that satisfies a
/// specified predicate and returns a collection containing each sequence
/// of elements in between each pair of such elements. The elements
/// satisfying the predicate are not included.
/// </summary>
/// <param name="splitWhat">The collection to be split.</param>
/// <param name="splitWhere">A predicate that determines which elements
/// constitute the separators.</param>
/// <returns>A collection containing the individual pieces taken from the
/// original collection.</returns>
public static IEnumerable<IEnumerable<T>> Split<T>(
this IEnumerable<T> splitWhat, Func<T, bool> splitWhere)
{
if (splitWhat == null)
throw new ArgumentNullException("splitWhat");
if (splitWhere == null)
throw new ArgumentNullException("splitWhere");
return splitIterator(splitWhat, splitWhere);
}
private static IEnumerable<IEnumerable<T>> splitIterator<T>(
IEnumerable<T> splitWhat, Func<T, bool> splitWhere)
{
int prevIndex = 0;
foreach (var index in splitWhat
.Select((elem, ind) => new { e = elem, i = ind })
.Where(x => splitWhere(x.e)))
{
yield return splitWhat.Skip(prevIndex).Take(index.i - prevIndex);
prevIndex = index.i + 1;
}
yield return splitWhat.Skip(prevIndex);
}
例如,在你的情況,你可以使用它像這樣:
var arr = new string[] { "foo", "bar", "jar", "\r", "a", "b", "c", "\r", "x", "y", "z", "\r" };
var results = arr.Split(elem => elem == "\r");
foreach (var result in results)
Console.WriteLine(string.Join(", ", result));
這將打印:
foo, bar, jar
a, b, c
x, y, z
(包括在最後一個空白行,因爲有在收藏結束時是"\r"
)。
可能的重複[如何將IEnumerable分成IEnumerable組的幾個組(http://stackoverflow.com/questions/1349491/how-can-i-split-an-ienumerablestring-into-groups-of -numeumerablestring) –
James
2010-09-21 10:00:56
不,它不是重複的 - 另一個是要求固定大小的組,這是要求基於分隔符的分割。 – Timwi 2010-09-21 10:10:33
@Timwi:*可能*是關鍵字在這裏.... – James 2010-09-21 14:21:55