1

I am trying to sort a 2D array of custom objects, inside each inner array, based on one of the properties. This sub-arrays each represent one class, the outer array all the classes in the school. My strategy is as such:

  1. Make a copy of the arry to provide a framework with the correct number of subarrays and indeces
  2. Pass a copy of the sub-array to variable
  3. Iterate over that array (the class) and pull out the last name from the object (which holds a number of other pieces of data on the child) and place it in an array that will be the index
  4. Sort the index
  5. Iterate over the class array, find the position of the last name in the index array, and insert the object into that index into the copied 'school'.

But this is not working. In some instances, one or two objects end up in the wrong place, in other instances it completely out of order. I have tried inspecting my index and comparing it with the 2D array, but the index is correct and I can't figure out why its not working. Here is the code:

var studentsInClass = // I have a function here that returns the 2D array of classes containing custom objects
      var sortedStudentsInClass = studentsInClass;
      var singleClassHolder = [];
      var studentIndex = [];
    
      //  each iteration is for a single class
      for(var i = 0; i < studentsInClass.length; i ++){
        studentIndex = [];
        singleClassHolder = studentsInClass[i];
    
        // populate the student reference index
        for(var j = 0; j < singleClassHolder.length; j++){
          studentIndex.push(singleClassHolder[j].ID);
        }
        studentIndex.sort();
    
        //  iterate through students of single class, placing them in alphabetical order
        for(var k = 0; k < singleClassHolder.length; k++){
          sortedStudentsInClass[i][studentIndex.indexOf(singleClassHolder[k].ID)] = singleClassHolder[k];
        }
      }
      return sortedStudentsInClass;
    }

In case the object is important:

function Child(last, first, id, classroom, serviceDays, eligibility){
      this.lastName = last;
      this.firstName = first;
      this.ID = id;
      this.class = classroom;
      this.maxServiceDays = serviceDays;
      this.eligibility = eligibility;
    }

And just a side note, it may seem extraneous having created the new singleClassHolder variable. After I noticed I did that, I removed it and just iterated through the 2D array, but that resulted in even more elements out of place.

Tzvi L
  • 45
  • 1
  • 7

1 Answers1

1

Make a copy of the arry

var sortedStudentsInClass = studentsInClass;

This won't make a copy. It only makes one variable reference the other in memory. They both refer to the same array in memory. See related answer here.

The easiest way to fix the code is by declaring sortedStudentsInClass as a new array.

var studentsInClass = get2DArrayOfClasses();
var sortedStudentsInClass = [];

/*...*/

for(var k = 0; k < singleClassHolder.length; k++){
  sortedStudentsInClass[i] = sortedStudentsInClass[i] || [];//declare inner array, if not present
  sortedStudentsInClass[i][studentIndex.indexOf(singleClassHolder[k].ID)] = singleClassHolder[k];
}
TheMaster
  • 45,448
  • 6
  • 62
  • 85
  • @iAmOren That(shallow) won't work, because `studentsInClass` is a 2D array. Even Deep copy(using jsonparse/stringify) won't work because it's a array of "classes". – TheMaster Jul 06 '20 at 10:18