Search Unity

Multidimensiol arrays

Discussion in 'Scripting' started by ozzwozz, Feb 16, 2018.

  1. ozzwozz

    ozzwozz

    Joined:
    Sep 15, 2015
    Posts:
    39
    Hi, I know that I should be using a jagged array or a list of arrays. I am currently trying to implement a jagged array however I cannot get it to work.
    I am trying to search an existing jagged array (that works and is all good) for the account type "STUDENT" and then put all of these into a new jagged array called StudentArray. However when I do this I get a NullReferenceException and I do not know why this is occurring.
    Code (csharp):
    1.  
    2.  public string[] users;
    3.     public string[][] userArray;
    4.     public string[] User = new string[3];
    5.     private string userDataString;
    6.     private int j;
    7.     public string[][] StudentArray;
    8.  
    9.     public string[][] UserSorting(string[][] userArray)
    10.     {
    11.         j = 0;
    12.         //for each row in user array
    13.         for (int i = 0; i <= userArray.Length; i++)
    14.         {
    15.             //Compares the stored account type to STUDENT
    16.             if (userArray[5] == "STUDENT")
    17.             {
    18.                 //for each user value copy into the new array
    19.                 for (int x = 0; x <= 5; x++)
    20.                 {
    21.                     print(userArray[x]);
    22.  
    23.                     StudentArray[j][x] = userArray[x];
    24.                 }
    25.                 //moves onto the next line ready for the next iteration
    26.                 j++;
    27.             }
    28.         }
    29.         return StudentArray;
    30.     }
    31. }
    32.  
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    What do you think you 'should be using a jagged array'?

    As for the exception, at what line of code does it happen? I'm willing to bet you're accessing a slot of the jagged array that doesn't have an array in it yet.

    Unlike true multi-dimensional arrays. When creating a jagged array you really have an array of arrays. And you need to instantiate both the array, and the multiple child arrays.

    A true multi-dimensional array initializes all at once.

    Again, why "should you be using a jagged array"? Jagged arrays are useful if any only if the column lengths are differ from row to row. Hence the name jagged, because row 1 might have 5 columns, but row 2 might have 2 columns.

    Multi-dimensional arrays remain square (in the case of 2d arrays). All rows have the same number of columns.
     
  3. ozzwozz

    ozzwozz

    Joined:
    Sep 15, 2015
    Posts:
    39
    I might need the opposite of a jagged array then... The columns are fixed (there will be 6) but the number of rows needs to be able to increase as for each new 'student. The error occurs on line 23.
     
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    Then yeah, a normal multi-dimensional array is what you want.

    Code (csharp):
    1.  
    2. public string[,] Students = new string[rowCount, 6];
    3.  
    Though really... I'd probably go with an array of structs/classes. So instead of rows and columns. You have rows and fields.

    Something like:

    Code (csharp):
    1.  
    2. public struct Student
    3. {
    4.      public string Name;
    5.      public string Grade;
    6.      public string Blargh;
    7. //three more fields, no idea what they're called
    8. }
    9.  
    10. public Student[] Students;
    11.  
     
  5. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    As far as multidimensional vs jagged array... I'd choose List<List<string>> over either, or a list of a custom class - probably the later.
     
  6. ozzwozz

    ozzwozz

    Joined:
    Sep 15, 2015
    Posts:
    39
    I looked into this briefly but I couldn't find a way of indexing and referencing points within the lists. Whereas at least with the array approach I could use Array[y][x]
     
  7. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    List has the same accessor as array. So you'd get the same [x][y] type access.

    As for if you had a list or array of custom class. You could write an index accessor for it.

    Code (csharp):
    1.  
    2. public struct Student
    3. {
    4.     public string Name;
    5.     public string Grade;
    6.     public string Blargh;
    7.  
    8.     public string this[int index]
    9.     {
    10.         get {
    11.             switch(index)
    12.             {
    13.                 case 0:
    14.                     return Name;
    15.                 case 1:
    16.                     return Grade;
    17.                 case 2:
    18.                     return Blargh;
    19.                 default:
    20.                     throw new System.IndexOutOfRangeException();
    21.             }
    22.         }
    23.     }
    24. }
     
  8. ozzwozz

    ozzwozz

    Joined:
    Sep 15, 2015
    Posts:
    39
    So, I would then instantiate a new child class for each student? how would I keep creating them, where are they stored/how do I reference them?
     
  9. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    They're stored in the array.

    Well... if it's a struct they're stored inline in the array, if they're a class they're on the heap and their reference is stored in the array.

    Just like the index of an array of strings has that string. You'd instead have a Student at that index instead.
     
  10. ozzwozz

    ozzwozz

    Joined:
    Sep 15, 2015
    Posts:
    39
    Okay I think I understand now, thank you. Finally could you explain the case, switch and default to me? this is the first time I've come across them
     
  11. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    It's a switch, it's sort of similar to a 'if else if' statement. Where the if clause is very simple. Basically what you switch on is compared by each case.

    So like that example I showed would be like saying this if statement:
    Code (csharp):
    1.  
    2. if(index == 0)
    3.    return Name;
    4. else if(index == 1)
    5.    return Grade;
    6. else if(index == 2)
    7.    return Blargh;
    8. else
    9.    throw new System.IndexOutOfRangeException();
    10.  
    Here's the msdn article on it:
    https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/switch

    It really only works where the if clause is a simple comparison clause. And if it's a super simple type like int, the compiler can actually optimize it into a much faster operation than an if else if statement.