Author Topic: Ranged String to Array  (Read 1787 times)

0 Members and 1 Guest are viewing this topic.

Jeff_M

  • King Gator
  • Posts: 4094
  • C3D user & customizer
Ranged String to Array
« on: January 05, 2022, 05:42:41 PM »
I had a string extension method to convert a Ranged String of numbers, such as "1-25,36,45,50-100", to an array of integers containing all number in the ranges. It has worked fine for years, however I now need it to work with uint numbers which can be much larger than a standard int. Which means this
Code - C#: [Select]
  1.        
  2. public static uint[] RangedStringToArray(this string value)
  3.         {
  4.             var result = value.Split(',')
  5.                               .Select(x => x.Split('-'))
  6.                               .Select(p => new { First = uint.Parse(p.First()), Last = uint.Parse(p.Last()) })
  7.                               .SelectMany(x => Enumerable.Range(x.First, x.Last - x.First + 1))
  8.                               .OrderBy(z => z);
  9.             return result.ToArray<uint>();
  10.         }
now fails due to the Enumerable.Range only accepting integers. I know enough about Linq to fumble my way through getting things to work, most of the time. I did not write the above code (for integers) and I am having a difficult time trying to get this to work with uints. I could rewrite this to not use Linq, but I'd like to know if it is possible to keep it mostly as it is.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8696
  • AKA Daniel
Re: Ranged String to Array
« Reply #1 on: January 05, 2022, 06:25:57 PM »
does it need to be unsigned ? does it work with int64?
edit: isnt IEnumerable a template? so IEnumerable<uint>?
« Last Edit: January 05, 2022, 06:31:57 PM by It's Alive! »

Jeff_M

  • King Gator
  • Posts: 4094
  • C3D user & customizer
Re: Ranged String to Array
« Reply #2 on: January 05, 2022, 10:45:04 PM »
Yes, must be uint type as Civil 3D CogoPint numbers are uints, thus allowing numbers up through 4 billion. The issue is that the Linq Enumerable.Range method only accepts ints

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8696
  • AKA Daniel
Re: Ranged String to Array
« Reply #3 on: January 06, 2022, 02:36:47 AM »
guess you need to roll it yourself, I rolled this on the dash of my 69 Camaro, not really

Code - C: [Select]
  1. namespace NetRange
  2. {
  3.     public static class Program
  4.     {
  5.  
  6.         public static IEnumerable<uint> GetUIntRange(uint start, uint count)
  7.         {
  8.             uint end = start + count;
  9.             for (uint i = start; i < end; ++i)
  10.                 yield return i;
  11.         }
  12.         public static uint[] RangedStringToArray(this string value)
  13.         {
  14.             var result = value.Split(',')
  15.                               .Select(x => x.Split('-'))
  16.                               .Select(p => new { First = uint.Parse(p.First()), Last = uint.Parse(p.Last()) })
  17.                               .SelectMany(x => GetUIntRange(x.First, x.Last - x.First + 1))
  18.                               .OrderBy(z => z);
  19.             return result.ToArray<uint>();
  20.         }
  21.  
  22.         static void Main(string[] args)
  23.         {
  24.           var range = RangedStringToArray("1-25,36,45,50-100");
  25.             foreach (var item in range)
  26.                 Console.WriteLine(item);
  27.             Console.ReadLine();
  28.         }
  29.     }
  30. }
  31.  

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Ranged String to Array
« Reply #4 on: January 06, 2022, 03:10:51 AM »
My 2 cents
Code - C#: [Select]
  1.         public static uint[] RangedStringToArray(this string value)
  2.         {
  3.             var result = value.Split(',')
  4.                               .Select(x => x.Split('-'))
  5.                               .Select(p => new { First = uint.Parse(p.First()), Last = uint.Parse(p.Last()) })
  6.                               .SelectMany(x => Range(x.First, x.Last))
  7.                               .OrderBy(z => z);
  8.             return result.ToArray<uint>();
  9.         }
  10.  
  11.         public static IEnumerable<uint> Range(uint start, uint end)
  12.         {
  13.             if (end < start) throw new ArgumentOutOfRangeException();
  14.             for (uint i = start; i <= end; i++)
  15.                 yield return i;
  16.         }
Speaking English as a French Frog

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Ranged String to Array
« Reply #5 on: January 06, 2022, 06:35:31 AM »
F# is so fun:
Code - F#: [Select]
  1. type String with
  2.     member str.RangedStringToArray =
  3.         str.Split(',')
  4.         |> Array.map (fun s -> s.Split('-'))
  5.         |> Array.collect (fun a -> [| UInt32.Parse(a.[0]) .. UInt32.Parse(a.[a.Length - 1]) |])

Code: [Select]
> "1-5,36,45,50-53".RangedStringToArray;;
val it : uint32 [] = [|1u; 2u; 3u; 4u; 5u; 36u; 45u; 50u; 51u; 52u; 53u|]
« Last Edit: January 07, 2022, 02:57:33 AM by gile »
Speaking English as a French Frog

Jeff_M

  • King Gator
  • Posts: 4094
  • C3D user & customizer
Re: Ranged String to Array
« Reply #6 on: January 06, 2022, 11:30:16 AM »
Thanks a lot guys, much appreciated!

Atook

  • Swamp Rat
  • Posts: 1029
  • AKA Tim
Re: Ranged String to Array
« Reply #7 on: January 06, 2022, 03:07:34 PM »
..I rolled this on the dash of my 69 Camaro, not really ..

You're a funny man Daniel   :2funny: