Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Problems with jagged arrays

Discussion in 'Scripting' started by benheyderman_unity, Jul 1, 2020.

  1. benheyderman_unity

    benheyderman_unity

    Joined:
    Jan 13, 2020
    Posts:
    4
    Hello!
    I am having some problems and I think it maybe that I am miss understanding/misusing jagged arrays.

    I am making an interactive gps sound art piece and I want the user to be guided on a random path on a map. To do this i have assigned each junction a number between 0 and 21 and have a jagged array that stores the adjacent junctions to each junction:

    Code (CSharp):
    1. int[][] routes =
    2.     new int [][]{
    3.         new int[] { 2, 12 }, //0
    4.         new int[] { 2 },
    5.         new int[] { 3, 0},
    6.         new int[] { 2, 13},
    7.         new int[] { 13, 5},
    8.         new int[] { 4, 15 },//5
    9.         new int[] { 17, 19, 9},
    10.         new int[] { 14, 16 },
    11.         new int[] { 14, 16, 9},
    12.         new int[] { 10, 8, 6 },
    13.         new int[] { 11, 14, 9 },//10
    14.         new int[] { 12, 10 },
    15.         new int[] { 11, 0 },
    16.         new int[] { 4, 3 },
    17.         new int[] { 7, 8, 10 },
    18.         new int[] { 16, 5, 13 },//15
    19.         new int[] { 7, 15, 8 },
    20.         new int[] { 5, 6, 18 },
    21.         new int[] { 19, 17, 20 },
    22.         new int[] { 21, 18, 6 },
    23.         new int[] { 21, 18 },//20
    24.         new int[] { 20, 19 }
    25.        
    26.     };
    27.    
    28.     int[][] editedRoutes;
    The first array stores the data and the second (editedRoutes) becomes a copy of the first so that I can edit it. I assign editedRoutes in the start function like this

    Code (CSharp):
    1. editedRoutes = routes;
    The following code is the majority of the script. I tried to clearly comment it and the issue is explained where you see the ************ (I hope this is clear enough to follow what is going on).

    Code (CSharp):
    1. // this function is called from another script and takes the arguement of a collider
    2.     public void TriggerNextJunction(Collider junctionCheck)
    3.     {
    4.         // Checks if the collider
    5.         // triggered variable
    6.         if (junctionCheck.gameObject == junctionObjects[currentJunction] && triggered == false)
    7.         {
    8.             triggered = true;
    9.             NextJunctionFunction();
    10.  
    11.         }
    12.     }
    13.    
    14.  
    15.     private void NextJunctionFunction()
    16.     {
    17.         // Temp single dimensional array
    18.         int[] routesFromNode;
    19.  
    20.         routesFromNode = editedRoutes[currentJunction];
    21.        
    22.         if (routesFromNode.Length == 1)// if there is only one adjacent junction, the list needs to be refreshed!
    23.         {
    24.             //*****************
    25.             // here i am trying to copy the unedited array (routes[currentJunction]) to the temp array (routesFromNode)!
    26.             // but is not working
    27.             // when I do this only the first element of routes[currentJunction] is stored in the temp array (routesFromNode)
    28.             // eg if the value of routes [1] is { 17, 19, 9} it is only copying {17}
    29.             // I have tested this by printing values and am fairly sure
    30.             //*****************
    31.  
    32.             routesFromNode = routes[currentJunction];
    33.         }
    34.  
    35.        
    36.         FindNextJunction(routesFromNode);
    37.  
    38.     }
    39.  
    40.    
    41.     private void FindNextJunction(int[] routesFromNode)
    42.     {
    43.         // selects a random adjacent junction from the temp array
    44.         index = Random.Range(0, routesFromNode.Length) ;
    45.         nextJunction = routesFromNode[index];
    46.  
    47.         //stops it doubling back on itself
    48.         if (nextJunction == previousJunction)
    49.         {
    50.             FindNextJunction(routesFromNode);
    51.         }
    52.         else {
    53.  
    54.             // this line removes the previous direction from the adjacent juntion list so that it won't get stuck in loops
    55.             // eg if i arrive at a junction where i have a choice of next moves i want to pick a different one to last time
    56.             routesFromNode = routesFromNode.Where(val => val != nextJunction).ToArray();
    57.  
    58.             // here I update editedRoutes with the temp array
    59.             editedRoutes[currentJunction] = routesFromNode;
    60.  
    61.             // updates previous and current junction values
    62.             previousJunction = currentJunction;
    63.             currentJunction = nextJunction;
    64.  
    65.             triggered = false;
    66.         }
    67.     }
    Thanks for your help, I hope this post is clear enough to follow. Any questions please ask :)
    Ben
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,893
    Your logic is a little too much for me to follow at the moment, but I think you may be suffering from a misconception about how arrays work in C#. Arrays are reference types which means that when you assign a variable to an instance of an array, you are not creating a copy of the array, you're just creating another reference to the same array.

    This statement reads to me that you are assuming your code here:
    Code (CSharp):
    1. editedRoutes = routes;
    is creating a copy of the array, where in reality you are just creating another variable that points to the same array. So when you make changes to
    editedRoutes
    you are also immediately and irrevocably making changes to
    routes
    because they are the same array.

    The same goes when you assign a variable to one of the sub-arrays in your jagged array, you are pointing to the actual sub-array and not a copy.

    Hopefully that is helpful?
     
    Yoreki likes this.
  3. benheyderman_unity

    benheyderman_unity

    Joined:
    Jan 13, 2020
    Posts:
    4
    Aahhhhhh yes that is exactly it. Sorry c# isn't my native language and i'm entirely self taught. How would I create a copy in editedRoutes?
    Thank you!
     
  4. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    265
    The Array type implements ICloneable, so you're able to make a (shallow) copy of the array using
    Code (CSharp):
    1. editedRoutes = (int[][])routes.Clone();
    Although since you are using a jagged array, you'll need to use a loop to copy it "properly":
    Code (CSharp):
    1. editedRoutes = new int[routes.Length][];
    2.  
    3. for (int i = 0; i < routes.Length; i++)
    4.     editedRoutes[i] = (int[])routes[i].Clone();
     
    PraetorBlue likes this.