WilliDK WilliDK - 3 years ago 139
Javascript Question

For loop inside for loop messing up variables

Hello I am trying to rearrange / sort my projectsDATA variable in alphabetical order. But when I run the sort() function in the console my code just messes up my variables. For instance if my projectsDATA variable would be:

var projectsDATA = [B, C, D, A];


If I would run my code with this variable the output would be [A, C, C, A], but the output doesn't seem "systematic".

I hope you understand my problem.

I have checked everything in my code to figure out how to solve this problem, and I have located that the problem occurs in the 3. for loop looking like this:

for(var index2 = 0; index2 < projectsDATAcopy.length; index2 = index2 + 1){
if (arrayChecked[index] == projectsDATAcopy[index2].title) {
console.log(arrayChecked[index], projectsDATA[index], projectsDATAcopy[index2]);
projectsDATA[index] = projectsDATAcopy[index2];
}
}


I know my code isn't perfect but any help would be appreciated :)

var projectsDATA = [
{
"href":"/cancerSimulation",
"theclass":"p5js websites",
"btnValue": "Cancer Simulator",
"title": "Aancer Simulation",
"description": "Cancer Simulation as addition to exam project Cancer Simulation as addition to exam project Cancer Simulation as addition to exam project Cancer Simulation as addition to exam project",
"date":[2017, "2017",5, "may"]
},
{
"href":"/encryptionProject",
"theclass":"websites",
"btnValue": "Facebook Encryption Tool",
"title": "Bacebook Encryption Tool",
"description": "Facebook Encryption Tool",
"date":[2016, "2016",12, "December"]
},
{
"href":"/encryptionProject",
"theclass":"websites",
"btnValue": "Facebook Encryption Tool",
"title": "Dacebook Encryption Tool",
"description": "Facebook Encryption Tool",
"date":[2016, "2016",12, "December"]
},
{
"href":"/encryptionProject",
"theclass":"websites",
"btnValue": "Facebook Encryption Tool",
"title": "Cacebook Encryption Tool",
"description": "Facebook Encryption Tool",
"date":[2016, "2016",12, "December"]
}
];

var projectsDATAcopy;
console.log(projectsDATA);
var arrayCheck = [];
var arrayChecked;

function sort() {
projectsDATAcopy = projectsDATA;
console.log(projectsDATAcopy, projectsDATA);
var sortValue = document.getElementById("sorting").value;

if (sortValue == "Alphabetical") {
for(var index3 = 0; index3 < projectsDATAcopy.length; index3++){
arrayCheck[index3] = projectsDATAcopy[index3].title;
console.log(arrayCheck);
}
arrayChecked = arrayCheck.sort();
console.log(arrayChecked);
console.log(projectsDATAcopy, projectsDATA);

for(var index = 0; index < arrayChecked.length; index = index +1){
console.log(arrayChecked[index]);
for(var index2 = 0; index2 < projectsDATAcopy.length; index2 = index2 + 1){
if (arrayChecked[index] == projectsDATAcopy[index2].title) {
console.log(arrayChecked[index], projectsDATA[index], projectsDATAcopy[index2]);
projectsDATA[index] = projectsDATAcopy[index2];
}
}
}
console.log(projectsDATA);
}
}

Answer Source

The simplest method is to use Array.prototype.sort.

projects.sort((projectX, projectY) => projectX.title.localeCompare(projectY.title));

Unfortunately, this mutates the original array which is often undesirable. We can mitigate this by using Array.prototype.slice to create a copy of the original array before sorting it. Since we are creating a brand new array we store the result of the sort operation in a new variable.

const sortedProjects = projects
  .slice()
  .sort((projectX, projectY) => projectX.title.localeCompare(projectY.title));

Here it is in action over your sample data

const projects = [{
    "href": "/cancerSimulation",
    "theclass": "p5js websites",
    "btnValue": "Cancer Simulator",
    "title": "Aancer Simulation",
    "description": "Cancer Simulation as addition to exam project Cancer Simulation as addition to exam project Cancer Simulation as addition to exam project Cancer Simulation as addition to exam project",
    "date": [2017, "2017", 5, "may"]
  },
  {
    "href": "/encryptionProject",
    "theclass": "websites",
    "btnValue": "Facebook Encryption Tool",
    "title": "Bacebook Encryption Tool",
    "description": "Facebook Encryption Tool",
    "date": [2016, "2016", 12, "December"]
  },
  {
    "href": "/encryptionProject",
    "theclass": "websites",
    "btnValue": "Facebook Encryption Tool",
    "title": "Dacebook Encryption Tool",
    "description": "Facebook Encryption Tool",
    "date": [2016, "2016", 12, "December"]
  },
  {
    "href": "/encryptionProject",
    "theclass": "websites",
    "btnValue": "Facebook Encryption Tool",
    "title": "Cacebook Encryption Tool",
    "description": "Facebook Encryption Tool",
    "date": [2016, "2016", 12, "December"]
  }
];

const sortedProjects = projects
  .slice()
  .sort((projectX, projectY) => projectX.title.localeCompare(projectY.title));
  
console.log(sortedProjects)

Remarks:

In the example code, I use const to declare my locals. When a name will not be rebound, const is superior to let since it conveys that information immediately to the reader. It frees the reader from having to think about the current state of the reference sortedProjects as they continue to read since it cannot change. Note the array that is referred to is still mutable.

slice create a shallow copy of an array or a subset of an array. When no arguments are specified, it simply creates a shallow copy of the entire array. By shallow copy, I mean that only the references to the objects at each index in the array are copied. The two arrays still share the same underlying objects, just arranged in different orders. The inline hyperlink to the MDN documentation for slice explains this behavior in detail.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download