Search Unity

How can i compare the current item in list with the next item ?

Discussion in 'Scripting' started by Chocolade, Aug 17, 2017.

  1. Chocolade

    Chocolade

    Joined:
    Jun 19, 2013
    Posts:
    933
    In this method i want first to check the distances.
    For example in the List pairList in index 0,1,2 all the distances are the same all of them are 10.
    So i want to add them to a List samedistances.

    Then to continue loop over the pairList until the next part where distances will be the same and add them also to the samedistances list.

    So in the end the samedistances list should be look something like:

    10
    10
    10
    20
    20
    44
    44
    44
    44
    50
    50


    But the way it is now it's adding first only two distances of 10 but there are three.
    Then it's adding one distance of 14.43455 but there is only one of that distance.

    And the first distance is 0 so not need to compare it at all.

    And last in the end i'm getting exception ArgumentOutOfRangeException: Argument is out of range since i'm doing i+1

    Code (csharp):
    1.  
    2. private void MoveInPath()
    3.     {
    4.         List<float> samedistances = new List<float>();
    5.  
    6.         for (int i = 0; i < pairList.Count; i++)
    7.         {
    8.             if (pairList[i].Distance == pairList[i+1].Distance)
    9.             {
    10.                 samedistances.Add(pairList[i].Distance);
    11.             }
    12.         }
    13.     }
    14.  
     
  2. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    945
    So you want a copy of pairlist but sorted? Just use YourList.Sort(Comparer<float>.default) on the copy.

    Code (CSharp):
    1. var samedistanceList = new List<float>(pairlist);
    2. samedistanceList.Sort(Comparer<float>.default);
     
  3. Chocolade

    Chocolade

    Joined:
    Jun 19, 2013
    Posts:
    933

    I can't
    I forgot how i built the pairList.

    In the top of the script i added:

    Code (csharp):
    1.  
    2. [System.Serializable]
    3.     public class PosDisPair
    4.     {
    5.         public float Distance;
    6.         public Vector3 Pos;
    7.     }
    8.  
    Then

    Code (csharp):
    1.  
    2. private List<PosDisPair> pairList = new List<PosDisPair>();
    3.  
    then

    Code (csharp):
    1.  
    2. private void FindDistances()
    3.     {
    4.         pairList = new List<PosDisPair>();
    5.  
    6.         for (int i = 0; i < objects.Count; i++)
    7.         {
    8.             PosDisPair pairToAdd = new PosDisPair();
    9.             pairToAdd.Distance = Vector3.Distance(EndStartPoints[0].transform.position, objects[i].transform.position);
    10.             pairToAdd.Pos = objects[i].transform.position;
    11.             pairList.Add(pairToAdd);
    12.         }
    13.  
    14.         pairList.Sort(delegate (PosDisPair a, PosDisPair b) {
    15.             return (a.Distance.CompareTo(b.Distance));
    16.         });
    17.  
    18.         TestDis();
    19.     }
    20.  
    And

    Code (csharp):
    1.  
    2. private void TestDis()
    3.     {
    4.         List<float> samedistances = new List<float>();
    5.  
    6.         pairList.Sort(Comparer<float>.Default);
    7.  
    8.         for (int i = 0; i < pairList.Count; i++)
    9.         {
    10.             if (pairList[i].Distance == pairList[i+1].Distance)
    11.             {
    12.                 samedistances.Add(pairList[i].Distance);
    13.             }
    14.         }
    15.     }
    16.  
    Now i tried the line:

    Code (csharp):
    1.  
    2. pairList.Sort(Comparer<float>.Default);
    3.  
    But getting error:

    cannot convert from 'System.Collections.Generic.Comparer<float>' to 'System.Collections.Generic.IComparer<LevelGenerator.PosDisPair>'
     
  4. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    945
    What is not working with your version with the delegate? it looks correct at a first glance
     
  5. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    Code (CSharp):
    1. private void FindDistances()
    2.     {
    3.         pairList = new List<PosDisPair>();
    4.         for (int i = 0; i < objects.Count; i++)
    5.         {
    6.             PosDisPair pairToAdd = new PosDisPair();
    7.             pairToAdd.Distance = Vector3.Distance(EndStartPoints[0].transform.position, objects[i].transform.position);
    8.             pairToAdd.Pos = objects[i].transform.position;
    9.             pairList.Add(pairToAdd);
    10.         }
    11.        
    12.           pairList= pairList.OrderBy(x => x.Distance).ToList();
    13.         });
    14.         TestDis();
    15.     }

    Code (CSharp):
    1.  
    2. pairList= pairList.OrderBy(x => x.Distance).ToList();
    3.  
    Will require
    using System.Linq;
    at the top, but should do what you want.
     
  6. Chocolade

    Chocolade

    Joined:
    Jun 19, 2013
    Posts:
    933

    This is working but i will explain why i tried to use the way i did it before:

    Code (csharp):
    1.  
    2. for (int i = 0; i < pairList.Count; i++)
    3.         {
    4.             if (pairList[i].Distance == pairList[i+1].Distance)
    5.             {
    6.                 samedistances.Add(pairList[i].Distance);
    7.             }
    8.         }
    9.  
    The reason is that i want to get random distance item out of same distances.
    For example if there three 10 distances then pic random one of them.
    The distances are the same three same 10 distances but each one have another position.

    pairList.Position

    So what i want is each group of same distances to pick one random.

    So for example there three distances of 10:

    Distance 10 - Position 1,,1,1
    Distance 10 - Position 1,23,45
    Distance 10 - Position 1,2,2

    So i want to pick a random distance and then use the position of this distance.
     
  7. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Well, you're not checking your List's bounds while you interate/index (it).
    You're comparing index 'i' with 'i+1' (while the loop is < ..Count), which means the last entry will always be out of bounds, at least.
    To expand on your design goal for wanting to compare as many that are the same, I'd say you could do an inner loop , maybe like:
    Code (csharp):
    1.  
    2. List<List<int>> samelist = new List<List<int>>();
    3. List<int> num = new List<int>();
    4. num.Add(5);
    5. num.Add(5);
    6. num.Add(7);
    7.             num.Add(7);
    8.             num.Add(7);
    9.             num.Add(7);
    10.             num.Add(10);
    11.             num.Add(20);
    12.             num.Add(74);
    13.             num.Add(74);
    14.             num.Add(2);
    15.             num.Add(98);
    16.             num.Add(98);
    17.             num.Add(98);
    18.             num.Add(98);
    19.             num.Add(98);
    20.             int lastmatch = -1;
    21.             int b = num.Count - 1;
    22.             for(int i = 0; i < num.Count; ++i){
    23.               if(i < b && num[i] == num[i+1]) {
    24.                   samelist.Add(new List<int>());
    25.                   samelist[samelist.Count-1].Add(num[i]);
    26.                   samelist[samelist.Count-1].Add(num[i]);
    27.                  int j = i+2;
    28.                  while(j <= b) {
    29.                      if(num[j] == num[i]){
    30.                          samelist[samelist.Count-1].Add(num[i]);
    31.                          ++i;
    32.                          ++j;
    33.                      }
    34.                      else break;
    35.                  }
    36.               }
    37.             }
    38.             for(int i = 0; i < samelist.Count; ++i){
    39.                 Console.WriteLine("Same List index " + i);
    40.                 Console.WriteLine("Value = " + samelist[i][0]);
    41.                 Console.WriteLine("Count = " + samelist[i].Count);
    42.             }
    43.  
    (written and moved from rextester - spacing's a little whacky). :)
     
  8. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    945
  9. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Am I missing something here? What is wrong with just stopping one element before the end of the list?

    Code (csharp):
    1. private void MoveInPath()
    2.     {
    3.         List<float> samedistances = new List<float>();
    4.  
    5.         for (int i = 0; i < pairList.Count - 1; i++)
    6.         {
    7.             if (pairList[i].Distance == pairList[i+1].Distance)
    8.             {
    9.                 samedistances.Add(pairList[i].Distance);
    10.             }
    11.         }
    12.     }
     
  10. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I had originally mentioned that (though didn't put it in my own example). However, I got the impression his question was asking for a little more than a snippet like that.. :)
     
  11. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Okay, just reread the question. My solution is only the first step, although it will fix the error.

    This is actually a surprisingly common problem I encounter in my day job. The trick is to look for the differences, not the equality. Its basically an edge detection problem.