Is there a way to break a string into pairs without looking at indexes? e.g. TVBMCVTVFGTVTB would be broken into a list of strings as such:
[TV,BM,CV,TV,FG,TV,TB]
Perhaps I should have worded the question to state is their a fun开发者_如何学Cction similar to string.join, or string.split when working with strings to break them into groups.
Oh come on, just use indexes like this:
public static class StringExtensions {
public static IEnumerable<string> TakeEvery(this string s, int count) {
int index = 0;
while(index < s.Length) {
if(s.Length - index >= count) {
yield return s.Substring(index, count);
}
else {
yield return s.Substring(index, s.Length - index);
}
index += count;
}
}
}
I have added no guard clauses.
Usage:
var items = "TVBMCVTVFGTVTB".TakeEvery(2);
foreach(var item in items) {
Console.WriteLine(item);
}
If you like some esoteric solutions:
1)
string s = "TVBMCVTVFGTVTB";
var splitted = Enumerable.Range(0, s.Length)
.GroupBy(x => x / 2)
.Select(x => new string(x.Select(y => s[y]).ToArray()))
.ToList();
2)
string s = "ABCDEFGHIJKLMN";
var splitted = Enumerable.Range(0, (s.Length + 1) / 2)
.Select(i =>
s[i * 2] +
((i * 2 + 1 < s.Length) ?
s[i * 2 + 1].ToString() :
string.Empty))
.ToList();
If you REALLY want to avoid using indexes...
You could use a Regex "\w\w" or "\w{2,2}" or some variation like that and MSDN - Regex.Matches method to get a MatchCollection which would contain the matches as pairs of characters. Change \w in the regex pattern to suit your needs.
List<string> result = new List<string>();
while (original.Length > 0)
{
result.Add(new String(original.Take(2).ToArray()));
original = new String(original.Skip(2).ToArray());
}
return result;
The LINQ probably uses indices somewhere internally, but I didn't touch any of them so I consider this valid. It works for odd-length originals, too.
Edit:
Thanks Heinzi for the correction. Demo: http://rextester.com/MWCKYD83206
Convert the string into a char array and then iterate along that making new strings out of pairs of characters.
1) Split list into pairs
var s = "TVBMCVTVFGTVTB";
var pairs = Enumerable.Range(0, s.Length / 2)
.Select(i => String.Concat(s.Skip(i * 2).Take(2)));
This will work if you know that s
always is of even length, or you don't accept, or don't care about, ending with singletons for strings with odd length.
2) Split list into pairs - include any singleton remainders
If you want to include singleton remainders, for odd length strings, you can simply use ceiling:
var s = "TVBMCVTVFGTVTB";
var pairs = Enumerable.Range(0, (int)Math.Ceiling(s.Length / 2D))
.Select(i => String.Concat(s.Skip(i * 2).Take(2)));
精彩评论