patterncsharpModerate
Compact a comma delimited number list into ranges
Viewed 0 times
numbercommadelimitedintorangeslistcompact
Problem
I'm looking for a clever way to do the following operation:
Take a list of numbers:
and compact it into a string like so:
With the following rule: only compress into a range (i.e. use a dash) when the count of numbers in the range is 3 or more.
I.e.:
This is my implementation, but I feel like it could be improved upon greatly:
As an example:
I have this working fine, I'm really just looking to find better ways to do the same operation because I think it's a fun one.
Take a list of numbers:
1, 2, 3, 4, 5, 12, 13, 14, 19and compact it into a string like so:
1-5, 12-14, 19With the following rule: only compress into a range (i.e. use a dash) when the count of numbers in the range is 3 or more.
I.e.:
1, 2, 4, 5 would result in: 1, 2, 4, 5 and NOT: 1-2, 4-5This is my implementation, but I feel like it could be improved upon greatly:
public string CompactNumberRanges(IEnumerable numbers,
int requiredRangeCount)
{
if (requiredRangeCount e).ToArray();
StringBuilder b = new StringBuilder();
for (int i = 0; i = requiredRangeCount)
{
b.Append(", ").AppendFormat("{0}-{1}", cv, sorted[i + count - 1]);
i += count - 1;
}
}
return b.ToString().Trim(',', ' '); ;
}As an example:
List numbers = new List
(
new int[] { 1, 2, 3, 4, 5, 12, 13, 14, 19 }
);
Console.WriteLine(CompactNumberRanges(numbers, 3));
// output: 1-5, 12-14, 19I have this working fine, I'm really just looking to find better ways to do the same operation because I think it's a fun one.
Solution
You could calculate a value to group on, i.e.
Then you just check how many items there is in each group to determine if it should be a range.
Example:
Output:
number - index. All consecutive numbers have the same value:index number number - index
----- ------ --------------
0 1 1
1 2 1
2 3 1
3 4 1
4 5 1
5 12 7
6 13 7
7 14 7
8 19 11Then you just check how many items there is in each group to determine if it should be a range.
Example:
List numbers = new List { 1, 2, 3, 4, 5, 12, 13, 14, 19 };
List items = numbers
.Select((n,i) => new { number = n, group = n - i })
.GroupBy(n => n.group)
.Select(g =>
g.Count() >= 3 ?
g.First().number + "-" + g.Last().number
:
String.Join(", ", g.Select(x => x.number))
)
.ToList();
Console.WriteLine(String.Join(", ", items));Output:
1-5, 12-14, 19Code Snippets
index number number - index
----- ------ --------------
0 1 1
1 2 1
2 3 1
3 4 1
4 5 1
5 12 7
6 13 7
7 14 7
8 19 11List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 12, 13, 14, 19 };
List<string> items = numbers
.Select((n,i) => new { number = n, group = n - i })
.GroupBy(n => n.group)
.Select(g =>
g.Count() >= 3 ?
g.First().number + "-" + g.Last().number
:
String.Join(", ", g.Select(x => x.number))
)
.ToList();
Console.WriteLine(String.Join(", ", items));1-5, 12-14, 19Context
StackExchange Code Review Q#90072, answer score: 18
Revisions (0)
No revisions yet.