Created
September 12, 2012 01:11
-
-
Save Dkowald/3703440 to your computer and use it in GitHub Desktop.
.NET generic Split<T>() extension
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace derek.kowald.util | |
{ | |
public static class IEnumerableExtension | |
{ | |
/// <summary> | |
/// Generic split operation, behave the same as string split. | |
/// </summary> | |
/// <remarks> | |
/// Other usefull split options, such as count and remove empty from string.split() | |
/// are better implemented with a little linq code: | |
/// .Take(n) and .Where(l => l.Any()) respectivly. | |
/// </remarks> | |
public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> source, Predicate<T> seperator) | |
{ | |
if (seperator == null) | |
{ throw new ArgumentNullException("seperator"); } | |
//loop each. | |
if (source != null && source.Any()) | |
{ | |
var next = new List<T>(); | |
foreach (var item in source) | |
{ | |
if (seperator(item)) | |
{ | |
yield return next; | |
next = new List<T>(); | |
} | |
else | |
{ | |
next.Add(item); | |
} | |
} | |
yield return next; | |
} | |
//xplicit empty enumeration (rahter than the confusing no-return option). | |
yield break; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace derek.kowald.test.util | |
{ | |
[TestClass] | |
public class IEnumerableExtensionTest | |
{ | |
[TestMethod] | |
public void Split_MultiLine() | |
{ | |
var data = ("A Line\nthe next line\n\n").ToList(); | |
var lines = data.Split(c => { return c == '\n'; }).ToList(); | |
Assert.AreEqual(4, lines.Count, "just like string split, an ending seperator is an empty last line."); | |
} | |
[TestMethod] | |
public void Split_RemovesSeperator() | |
{ | |
var data = "A line \n"; | |
var lines = data.Split(c => c == '\n'); | |
Assert.AreNotEqual('\n', lines.First().Last(), "ending new-line is striped."); | |
} | |
[TestMethod] | |
public void Split_EndsWithSeperator() | |
{ | |
var data = "A Single line\n".ToList(); | |
var lines = data.Split(c => c == '\n'); | |
Assert.AreEqual(2, lines.Count(), "ending seperator indicates a empty last line, same as string.split"); | |
} | |
[TestMethod] | |
public void Split_NoSeperator() | |
{ | |
var data = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; | |
var lines = data.Split(i => i == 0); | |
Assert.AreEqual(1, lines.Count()); | |
} | |
[TestMethod] | |
public void Split_SeqOfSeperator() | |
{ | |
var data = "Multi \n\n\n Seperators\n".ToList(); | |
var lines = data.Split(c => c =='\n'); | |
Assert.AreEqual(5, lines.Count()); | |
} | |
[TestMethod] | |
public void Split_EmptyLine_IsEmptyList() | |
{ | |
var data = "\n\n".ToList(); | |
var lines = data.Split(c => c == '\n').ToList(); | |
Assert.AreEqual(3, lines.Count()); | |
Assert.IsNotNull(lines.First()); | |
Assert.AreEqual(0, lines.First().Count()); | |
} | |
[TestMethod] | |
public void Split_NullOrEmptySource() | |
{ | |
IEnumerable<int> nullData = null; | |
var emptyData = String.Empty.ToList(); | |
var nullLines = nullData.Split(i => i < 0); | |
var emptyLines = emptyData.Split(c => c == '\n'); | |
Assert.AreEqual(0, nullLines.Count()); | |
Assert.AreEqual(0, emptyLines.Count()); | |
} | |
[TestMethod] | |
public void Split_NoPredicate() | |
{ | |
var data = "some sample data.".ToList(); | |
Exception error = null; | |
try | |
{ | |
var lines = data.Split(null).ToList(); | |
} | |
catch (ArgumentNullException ex) | |
{ | |
error = ex; | |
} | |
Assert.IsNotNull(error, "null pred, cause error."); | |
} | |
[TestMethod] | |
public void Split_PredThrows() | |
{ | |
var data = new[] { 3, 5, 6, 2, 6, 4 }; | |
ApplicationException error = null; | |
try | |
{ | |
data.Split(i => | |
{ | |
if (i == 6)throw new ApplicationException("broken"); | |
return false; | |
}).ToList(); | |
} | |
catch (ApplicationException ex) | |
{ | |
error = ex; | |
} | |
Assert.IsNotNull(error, "just passes out the predicate error."); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment