There is an array of variable size, for example:

string[] elements_1; elements_1[0] = "17-24 36-41 53-58 138-143 155"; elements_1[1] = "13-16 32 49-52 66-69"; elements_1[2] = "13-16 32-35 49-52 66 83 100-103"; ... 

How to pull out all the numbers from the [i] -th element of the array, taking into account the intervals and put into a two-dimensional array int [i, j] RESULT, in which i = i of the first array, j contains the corresponding array of the obtained numbers?

  • 3
  • "taking into account intervals" - ?? - Igor
  • @Igor, probably 13,14,15,16,32,49,50,51,52,66,67,68,69 for elements_1[1] - Qwertiy
  • Yes that's right. - pucher
  • to the array int[i,j] with only very large redundancy, better in int[i][j] - rdorn

3 answers 3

One line is parsed into a numeric sequence with the following code:

 .Split().Select(s => Array.ConvertAll(s.Split('-'), int.Parse)).SelectMany(d => Enumerable.Range(d.First(), d.Last() - d.First() + 1)) 

Example of work: https://ideone.com/mtqXpo

  • Cool way :) I understood how I managed with the range. - Qwertiy
  • Instead of Array.ConvertAll(s.Split('-'), int.Parse) you can simply s.Split('-').Select(int.Parse) , you get the same thing. - VladD
  • @VladD, you can, but made a special Array , because will work First() / Last() - Andrey NOP
  • Oh yes, you need to materialize the inside . ideone.com/5kJaz7 - VladD
  • @VladD, you can, yes. If there was golf, one character could be won. And so, I think that Array.ConvertAll should be more efficient than ToList / ToArray , since the length of the array is known in advance, and after Select is no longer. - Andrey NOP

In Javascript, like this, I’ll rewrite linq a bit later:

 var data = ["17-24 36-41 53-58 138-143 155", "13-16 32 49-52 66-69", "13-16 32-35 49-52 66 83 100-103"] function range(l, r) { var res = []; for (; l<=r; ++l) res.push(l) return res; } function flatten(arr) { return [].concat(...arr) } var res = data.map(s => flatten(s.split(" ").map(s => s==+s ? +s : (s=s.split("-"), range(+s[0], +s[1]))))) console.log(res) 
 .as-console-wrapper.as-console-wrapper { max-height: 100vh } 

And here is the C # version: https://ideone.com/gMSZKz

 using System; using System.Linq; public class Test { public static void Main() { var data = new string [] { "17-24 36-41 53-58 138-143 155", "13-16 32 49-52 66-69", "13-16 32-35 49-52 66 83 100-103" }; int[][] res = data.Select(line => line.Split().SelectMany(s => { int x; if (int.TryParse(s, out x)) return Enumerable.Repeat(x, 1); var lr = s.Split('-'); int l = int.Parse(lr[0]), r = int.Parse(lr[1]); return Enumerable.Range(l, r-l+1); }).ToArray()).ToArray(); foreach (var line in res) Console.WriteLine("{0}\n===", String.Join(" ", line)); } } 
  • Thanks, of course, but there seems to be a label like "C #" :). - pucher
  • @pucher, yes, I'll redo it now :) - Qwertiy
  • @pucher, done. - Qwertiy
  • The new C # has out var x , by the way. - VladD
  • @VladD, I think so too, but ideone doesn't want to compile: ideone.com/JAJPf4 - Qwertiy
 var data = new[] { "17-24 36-41 53-58 138-143 155", "13-16 32 49-52 66-69", "13-16 32-35 49-52 66 83 100-103", }; foreach(var row in data.Split().ParseRange()) Console.WriteLine(string.Join(" ", row)); 

To make it work we add extension methods.

 public static class ArrayEntentions { public static IEnumerable<IEnumerable<string>> Split(this IEnumerable<string> source, char separator = ' ') { return source.Select(x => x.Split(separator)); } public static IEnumerable<IEnumerable<int>> ParseRange(this IEnumerable<IEnumerable<string>> source) { return source.Select(ArrayEntentions.Parse); } public static IEnumerable<int> Parse(this IEnumerable<string> source) { foreach(var s in source) { int o; if (int.TryParse(s, out o)) { yield return o; } else { var interval = s.SplitInterval(); foreach(var i in Enumerable.Range(interval.Item1, interval.Item2)) yield return i; } } } public static Tuple<int, int> SplitInterval(this string source, char separator = '-') { var cells = source.Split(separator); if (cells.Length != 2) throw new FormatException(); var start = int.Parse(cells[0]); var count = int.Parse(cells[1]) - start + 1; return Tuple.Create(start, count); } }