MKF
MKF

Reputation: 596

Sorting nested arrays

I'm using javascript to sort nested arrays. This works as I expect it to:

arr = [[223, "VA", "BP8"], [24, "VA", "BP31"], [127, "VA", "BP1"]]

arr.sort(function(a,b){
    return a[2] > b[2];
});

//[[127, "VA", "BP1"], [24, "VA", "BP31"], [223, "VA", "BP8"]]

But when I do this in the browser with more data, nothing gets sorted after doing the sort function. It remains exactly as it was before calling sort. Any idea what's wrong here? The above example is the exact data being sorted on in the below example, each nested array is just longer in length with more data being pushed to it.

tableData = [];
arrayUtil.forEach(event.features, function (feature) {
    var rowData = [];
    rowData.push(feature.attributes.OBJECTID);
    rowData.push(feature.attributes.StateID);
    rowData.push(feature.attributes.Point);
    rowData.push(feature.attributes.PatchNum);
    rowData.push(developed(feature.attributes.IsDeveloped));
    rowData.push(cropType(feature.attributes.CropTypeID));
    rowData.push(feature.attributes.CropResidue);
    rowData.push(feature.attributes.CnpyOver12);
    rowData.push(feature.attributes.CnpyDecid);
    rowData.push(feature.attributes.CnpyConif);
    rowData.push(feature.attributes.ShrubCover);
    rowData.push(feature.attributes.ShbHiStemsDens);
    rowData.push(feature.attributes.GrassCover);
    rowData.push(feature.attributes.ForbCover);
    rowData.push(feature.attributes.FrbAsProtect);
    rowData.push(feature.attributes.ForbSpecies);
    rowData.push(feature.attributes.BareGround);
    rowData.push(herbHght(feature.attributes.HerbHeight));
    var overstoryDesc = coarseClassify(feature.attributes.Overstory);
    rowData.push(overstoryDesc);
    rowData.push(fineClassify(feature.attributes.Understory, overstoryDesc));
    rowData.push(qhStatus(feature.attributes.OfficialQH));
    rowData.push(formatDate(feature.attributes.ObsvDate));
    rowData.push(collectionType(feature.attributes.ObsvType));
    tableData.push(rowData);
});

//Sort the tableData list of lists by Point name
tableData.sort(function (a, b) {
    return a[2] > b[2];
});

Upvotes: 3

Views: 5108

Answers (1)

Pointy
Pointy

Reputation: 413702

The callback function to .sort() should return a number, not a boolean. The number should be less than zero to indicate that the two values are already in the proper order, or greater than zero to indicate that they are in reverse order, or zero to indicate that they're equivalent.

Thus what you want is something like

tableData.sort(function(a, b) {
  return a[2].localeCompare(b[2]);
});

The string .localeCompare() function does exactly the thing that you want for a sort comparator. However, you may see older string-based comparator functions that do something like this:

tableData.sort(function(a, b) {
  if (a < b) return -1;
  if (a > b) return 1;
  return 0;
});

which is more explicit.

edit — now that I re-examine the original code in the question, it may be that you want to sort in reverse order of that key. If that's the case, you can simply negate the call to .localeCompare() or compare b to a instead of a to b.

Upvotes: 3

Related Questions