Given the pair of 2 strings "2-4,6-8"
I want to separate these 2 pairs and find all numbers between those range.
So first pair 2-4
should return me 2, 3, 4
Second pair 6-8
should return 6, 7, 8
I tried below code
var splittedString = ln.Split(",");
var firstPair = splittedString[0];
var secondPair = splittedString[1];
var splittedFirstPair = firstPair.Split("-");
IEnumerable<int> firsPairRange = Enumerable.Range(
Convert.ToInt32(splittedFirstPair[0]),
Convert.ToInt32(splittedFirstPair[1]));
var splittedSecondPair = secondPair.Split("-");
IEnumerable<int> secondPairRange = Enumerable.Range(
Convert.ToInt32(splittedSecondPair[0]),
Convert.ToInt32(splittedSecondPair[1]));
But the variable firsPairRange gives me output 2,3,4,5
and the variable secondPairRange gives me output 6,7,8,9,10,11,12,13
I don't understand why and how to fix it?
CodePudding user response:
Enumerable.Range
has two parameters:
- the start
- the count(!)
So this gives you already enough information to fix it. Your start is 2 and the count is 4 because of 2-4
but you want 4-2 1=3
as count:
IEnumerable<int> firstPairRange = Enumerable.Empty<int>();
if (splittedFirstPair.Length == 2
&& int.TryParse(splittedFirstPair[0], out int first)
&& int.TryParse(splittedFirstPair[1], out int second)
&& second >= first)
{
int count = second - first 1;
firstPairRange = Enumerable.Range(first, count);
}
CodePudding user response:
In general case (negative numbers, single numbers) when we allow strings like this
-9,2-4,6-8,-5,7,-3-5,-8--2
we can put it as
private static IEnumerable<IEnumerable<int>> Ranges(string text) {
foreach (var range in text.Split(',')) {
var match = Regex.Match(range,
@"^\s*(?<left>-?[0-9] )\s*-\s*(?<right>-?[0-9] )\s*$");
if (match.Success) {
int left = int.Parse(match.Groups["left"].Value);
int right = int.Parse(match.Groups["right"].Value);
yield return Enumerable.Range(left, right - left 1);
}
else
yield return new[] { int.Parse(range) };
}
}
Demo:
string text = "-9,2-4,6-8,-5,7,-3-5,-8--2";
var result = string.Join(Environment.NewLine, Ranges(text)
.Select(range => string.Join(", ", range)));
Console.Write(result);
Output:
-9
2, 3, 4
6, 7, 8
-5
7
-3, -2, -1, 0, 1, 2, 3, 4, 5
-8, -7, -6, -5, -4, -3, -2
CodePudding user response:
string ln = "2-4,6-8";
var splittedString = ln.Split(',').Select(x => x.Split('-').Select(int.Parse).ToArray());
int[] first = splittedString.ElementAt(0);
int[] second = splittedString.ElementAt(1);
var firstPairRange = Enumerable.Range(first[0], first[1] - first[0] 1);
var secondPairRange = Enumerable.Range(second[0], second[1] - second[0] 1);
CodePudding user response:
You are providing wrong values to Enumerable.Range() function. Its syntax is Enumerable.Range(int start, int count). In start, you have to give first integer in the sequence and in count, you have to give number of integers to be generated in sequence. If you correct your count, right sequence will be generated. Replace your lines with the following lines:
IEnumerable<int> firsPairRange = Enumerable.Range(Convert.ToInt32(splittedFirstPair[0]), Convert.ToInt32(splittedFirstPair[1]) - Convert.ToInt32(splittedFirstPair[0]) 1);
IEnumerable<int> secondPairRange = Enumerable.Range(Convert.ToInt32(splittedSecondPair[0]), Convert.ToInt32(splittedSecondPair[1]) - Convert.ToInt32(splittedSecondPair[0]) 1);