A generic update for sp1234’s wonderful solution
This article is related to sp1234’s wonderful solution to this question
http://topic.csdn.net/u/20100318/14/22ea65ac-2fde-4587-adf6-3d8ab73ca367.html?39422
Here I briefly explain what the question is and how sp1234 solved it using such a beautiful way.
To split a byte[] by some criteria(here the criteria is byte = 94)
byte[] tm = new byte[] { 94, 1, 2, 3, 94, 2, 3, 4, 5, 94, 3, 4 };
and sp1234’s codes are:
var result = tm.Aggregate(new List<List<byte>>(),(container,b)=>
{
if (container.Count == 0 || b == 94) container.Add(new List<byte>()); else container.Last().Add(b);
return container;
});
I want to extend the solution depending on sp1234’s idea, to make the splitting generic, not only limited to byte, string, int,…. Etc. so I designed such an extension method
public static List<List<T>> GenericSplit<T>(this IEnumerable<T> source, Predicate<T> criteria)
{
return source.Aggregate(new List<List<T>>(), (container, item) =>
{
if (container.Count == 0 || criteria(item))
container.Add(new List<T>());
else
container.Last().Add(item);
return container;
});
}
This method is based on sp1234’s method, the only different is that I used a Predicate<T> criteria replacing x == 94
Now we can do a great test. To split the byte[] by value = 94. We write
byte[] tm = new byte[] { 94, 1, 2, 3, 94, 2, 3, 4, 5, 94, 3, 4 };
tm.GenericSplit<byte>(s => s == 94);
how about we has a group of text line stored in a text file, after loading the file’s content into a string[], we want to split the text by some criteria(for example, split by value start with ‘-----’)
say the text[] like this
string[] lines = new string[]
{
"Among the world's most widely spoken languages, ",
"articles are found almost exclusively in Indo-European ",
"and Semitic",
"----------",
" languages; Chinese, Japanese, Hindi, Malay,",
" and Russian have no articles, strictly speaking, even ",
"though certain words may optionally be used like articles if needed.",
"Linguists believe that the common ancestor of the Indo-",
"------------",
"European languages (i.e., the Proto-Indo-European language) ",
"did not have articles. Most of the languages in this family",
"do not",
"------------",
"have definite or indefinite articles; there is no a",
"rticle in Latin, Sanskrit, Persian, nor in some modern Indo",
"------------",
"-European languages, such as the Baltic languages and most ",
"Slavic languages",
". Although Classical Greek has a definite "
};
To split the text block by “------”, we write such a code
var result1 =lines.GenericSplit<string>(s => s.StartsWith("---"));
Console.WriteLine(result1);
If next time you want to split the text block by any line lenth < 10, we can write like this
var result1 =lines.GenericSplit<string>(s => s.Length < 10);
Console.WriteLine(result1);
Quite convince, en..?
Hope you guys like it and again thanks to sp1234