-2

I have a problem where I want to create a jagged array. But the size of this jagged array is variable. Does this work the same way as filling an normal array like this?

int[] terms = new int[400];
for (int runs = 0; runs < 400; runs++)
{
    terms[runs] = value;
}

The values I use are defined like this:

public static string[] nodeCassette0 = { "03", "08" };
public static string[] nodeCassette1 = { "04", "09" };
public static string[] nodeCassette2 = { "05", "10" };
public static string[] nodeCassette3 = { "06", "11" };
public static string[] nodeCassette4 = { "07", "12" };

Depending on the size required by the user a new variable nodeCassette needs to be filled according to the required size. The order in which the array is filled is always the same, it starts at 0 and ends at 4.

This should be like that but I don't know how to dynamically create it:

public string[][] nodeCassette =
{ 
    nodeCassette0,
    nodeCassette1,
    nodeCassette2,
    nodeCassette3,
    nodeCassette4
};
  • 3
    You should be using `List` instead of `int[]` then you don't need to specify the size – Liam May 12 '21 at 12:00
  • This is an easy fix, but how do i create the function to fill this list? – Zjwamerjong May 12 '21 at 12:02
  • Yes, it works the same way as filling a normal array. – Antonín Lejsek May 12 '21 at 12:05
  • `var terms = new List();` and inside your loop `terms.Add(value)`. – nilsK May 12 '21 at 12:06
  • @Liam - That's not true. – Enigmativity May 12 '21 at 12:44
  • @Zjwamerjong What you need for `nodeCassette` is not a [jagged array](https://learn.microsoft.com/dotnet/csharp/programming-guide/arrays/jagged-arrays), as I understand. You can use a [`List`](https://learn.microsoft.com/dotnet/api/system.collections.generic.list-1)`` (or a `Dictionary` or perhaps a [HashSet](https://learn.microsoft.com/dotnet/api/system.collections.generic.hashset-1)) because here you describe a collection of arrays of strings: does it fit? –  May 12 '21 at 12:59
  • @OlivierRogier from my understanding right now I can use a list but what I don't get is how to get the right amount of elements in this list/array. Or can I just use the whole list and get the needed elements out of the list. – Zjwamerjong May 12 '21 at 14:08
  • @Zjwamerjong Using a list you can add each array of string one by one dynamically as and when needed. but I don't understand what you mean by "*how to get the right amount of elements*". For example: is this amount got from a user input or is it calculated from something? –  May 12 '21 at 14:28
  • @OlivierRogier by the right amount of elements I mean the input from the user. This will be between 1 and 5. – Zjwamerjong May 14 '21 at 07:47
  • @Zjwamerjong Ok. But the problem is that I don't understand what you are trying to do. Do you need `int.TryParse(Console.ReadLine(), out var count); var items = new List(count);` where count is the optimized capacity (default internal list's array size) while items not yet initialized ? And then you want to add some `nodeCassetteX` from 0 to 4 according to the user's choice ? Thus you will get for example `{nodeCassette0, nodeCassette1}` if 2 or `{nodeCassette0, nodeCassette1, nodeCassette2}` if 3. Is that? –  May 14 '21 at 07:59
  • 1
    @OlivierRogier I'm reading the value from a windows form so the first part is almost correct. However the rest in your comment as far as I know is completly correct – Zjwamerjong May 14 '21 at 08:21

2 Answers2

0

Here's an example of how to create such a jagged array:

int[] sizes = new int[] { 3, 2, 1, 1, 3 };

int[][] jagged = new int[sizes.Length][];

for (int i = 0; i < sizes.Length; i++)
{
    jagged[i] = new int[sizes[i]];
    for (int j = 0; j < sizes[i]; j++)
    {
        jagged[i][j] = (i + 1) * (j + 1);
    }
}

That produces:

jagged


It's no different with strings:

int[] sizes = new int[] { 3, 2, 1, 1, 3 };

string[][] jagged = new string[sizes.Length][];

for (int i = 0; i < sizes.Length; i++)
{
    jagged[i] = new string[sizes[i]];
    for (int j = 0; j < sizes[i]; j++)
    {
        jagged[i][j] = $"{i}_{j}";
    }
}
Enigmativity
  • 113,464
  • 11
  • 89
  • 172
0

We can use reflexion and Linq.

using System.Reflection;
using System.Linq;

Having this dedicated class to store the arrays by default, as well as initialize a complete list of possible elements, and offer a method to obtain a slice, i.e. a list made up of the first n-elements:

static class DefaultArrays
{
  static public string[] NodeCassette0 = { "03", "08" };
  static public string[] NodeCassette1 = { "04", "09" };
  static public string[] NodeCassette2 = { "05", "10" };
  static public string[] NodeCassette3 = { "06", "11" };
  static public string[] NodeCassette4 = { "07", "12" };

  static public List<string[]> All { get; private set; }

  static public List<string[]> Take(int count)
  {
    return All.Take(count).ToList();
  }

  static public void Initialize()
  {
    All = typeof(DefaultArrays).GetFields()
                               .Where(field => field.FieldType == typeof(string[]))
                               .OrderBy(field => field.Name.Length)
                               .ThenBy(field => field.Name)
                               .Select(field => (string[])field.GetValue(null))
                               .ToList();
  }

  static DefaultArrays()
  {
    Initialize();
  }
}

The Initialize method is created this way to possibly allow updating of the entire list in case the arrays are modified at runtime, otherwise the code can be placed directly in the constructor and all arrays marked readonly.

Here is the algorithm for All:

  • We get all fields of the static class by its type name.
  • We filter to select only those being of type array of string.
  • We order by the fields name string length.
  • Then by this name, thus we finally get for example 1, 2, 30, 40 from 40, 30, 2, 1.
  • We do a projection to get the reference of the value instead of the field name using it.
  • And we transform the Linq query into a List<string> object instance to return.

It uses a pseudo-natural numeric sort assuming all arrays are named:

"[same_same][number_without_trailing_left_0]"

Else we can use a custom comparer:

How do I sort strings alphabetically while accounting for value when a string is numeric?

sort string-numbers

Test

var slice = DefaultArrays.Take(3);

string msg = string.Join(Environment.NewLine, slice.Select(item => string.Join(", ", item)));

Console.WriteLine(msg);

Output

03, 08
04, 09
05, 10

Warning

The slice contains a list of references toward original arrays, thus any modification of a cell of an array in this list will be reflected in the matching array in the static class.

Else we need to copy the arrays with Array.Copy instead of using Linq.Take:

  static public List<string[]> TakeCopy(int count)
  {
    var list = new List<string[]>();
    foreach ( int index in Enumerable.Range(0, Math.Min(count, All.Count)))
    {
      int length = All[index].Length;
      var array = new string[length];
      Array.Copy(All[index], array, length);
      list.Add(array);
    }
    return list;
  }