Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JS sort is not a function

I'm currently attempting to sort an object although I've been facing a data.sort is not a function error.

I have taken inspiration from the following StackOverflow answer: Sort Table by click in header tag regardless of it is numeric, alphabetical or date.

I have also had a browse of other questions and haven't yet managed to fix my issue, as it tends to lead to other issues such as the value being undefined.

Here is my object:

{
    "2010-01": {
        "item1": 324,
        "item2": 1075,
        "item3": 940,
        "item4": 441,
        "item5": 1040,
        "item6": 898,
        "item7": 1343
    },
    "2011-02": {
        "item1": 295,
        "item2": 958,
        "item3": 904,
        "item4": 434,
        "item5": 1038,
        "item6": 793,
        "item7": 1246
    },
    "2012-03": {
        "item1": 314,
        "item2": 1062,
        "item3": 980,
        "item4": 494,
        "item5": 1158,
        "item6": 914,
        "item7": 1461
    },
    "2008-04": {
        "item1": 336,
        "item2": 1022,
        "item3": 987,
        "item4": 488,
        "item5": 1014,
        "item6": 792,
        "item7": 1382
    },
    "2007-05": {
        "item1": 332,
        "item2": 1073,
        "item3": 1002,
        "item4": 512,
        "item5": 1104,
        "item6": 840,
        "item7": 1368
    },
    "2005-06": {
        "item1": 311,
        "item2": 981,
        "item3": 837,
        "item4": 432,
        "item5": 1002,
        "item6": 801,
        "item7": 1265
    },
    "2014-07": {
        "item1": 321,
        "item2": 1049,
        "item3": 921,
        "item4": 489,
        "item5": 963,
        "item6": 881,
        "item7": 1340
    },
    "2015-08": {
        "item1": 294,
        "item2": 1071,
        "item3": 960,
        "item4": 506,
        "item5": 910,
        "item6": 885,
        "item7": 1312
    },
    "2016-09": {
        "item1": 281,
        "item2": 1020,
        "item3": 952,
        "item4": 502,
        "item5": 1068,
        "item6": 914,
        "item7": 1397
    },
    "2009-10": {
        "item1": 319,
        "item2": 1058,
        "item3": 985,
        "item4": 546,
        "item5": 1184,
        "item6": 1031,
        "item7": 1448
    },
    "2005-11": {
        "item1": 300,
        "item2": 1021,
        "item3": 967,
        "item4": 474,
        "item5": 1176,
        "item6": 1009,
        "item7": 1387
    },
    "2017-12": {
        "item1": 307,
        "item2": 1027,
        "item3": 924,
        "item4": 427,
        "item5": 1024,
        "item6": 844,
        "item7": 1300
    }
}

My function for sorting, which at the minute I've only started by trying order the first item in either ascending or descending order.

function sortData(key, data, type) {
        if (key === "item1") {
          if (type === "asc") {
            data.sort(function(a, b) {
              return a[key] > b[key];
            });
          } else {
            data.sort(function(a, b) {
              return a[key] < b[key];
            });
          }
        }
        return data;
      }

The data is the object, and I've tried to pass it like such: sortData('item1', [data], 'asc'); as opposed to just data but with no luck. If someone could shed some light as to what I'm doing wrong that would be great.

like image 853
Matt Kent Avatar asked Jan 29 '23 18:01

Matt Kent


1 Answers

The problem is that the data is not an array and sort is an array method. You can use Object.keys to get an array of the keys, sort that and then populate with the values with a forEach:

let unsorted_data = { "2010-01": { "item1": 324, "item2": 1075, "item3": 940, "item4": 441, "item5": 1040, "item6": 898, "item7": 1343 }, "2011-02": { "item1": 295, "item2": 958, "item3": 904, "item4": 434, "item5": 1038, "item6": 793, "item7": 1246 }, "2012-03": { "item1": 314, "item2": 1062, "item3": 980, "item4": 494, "item5": 1158, "item6": 914, "item7": 1461 }, "2008-04": { "item1": 336, "item2": 1022, "item3": 987, "item4": 488, "item5": 1014, "item6": 792, "item7": 1382 }, "2007-05": { "item1": 332, "item2": 1073, "item3": 1002, "item4": 512, "item5": 1104, "item6": 840, "item7": 1368 }, "2005-06": { "item1": 311, "item2": 981, "item3": 837, "item4": 432, "item5": 1002, "item6": 801, "item7": 1265 }, "2014-07": { "item1": 321, "item2": 1049, "item3": 921, "item4": 489, "item5": 963, "item6": 881, "item7": 1340 }, "2015-08": { "item1": 294, "item2": 1071, "item3": 960, "item4": 506, "item5": 910, "item6": 885, "item7": 1312 }, "2016-09": { "item1": 281, "item2": 1020, "item3": 952, "item4": 502, "item5": 1068, "item6": 914, "item7": 1397 }, "2009-10": { "item1": 319, "item2": 1058, "item3": 985, "item4": 546, "item5": 1184, "item6": 1031, "item7": 1448 }, "2005-11": { "item1": 300, "item2": 1021, "item3": 967, "item4": 474, "item5": 1176, "item6": 1009, "item7": 1387 }, "2017-12": { "item1": 307, "item2": 1027, "item3": 924, "item4": 427, "item5": 1024, "item6": 844, "item7": 1300 } };

function sortData(key, data, type) {
  let ordered = {};
  let compareFunction = function(a, b) {
    return data[b][key] - data[a][key];
  };
  if (type === "asc") {
    compareFunction = function(a, b) {
      return data[a][key] - data[b][key];
    }
  }
  Object.keys(data).sort(compareFunction).forEach(function(key) {
    ordered[key] = data[key];
  });
  return ordered;
}


console.log(sortData("item1", unsorted_data, 'asc'));

And you can still pass your custom compare functions for asc and desc. order to sort, but I have omitted that for simplicity.

like image 178
mdatsev Avatar answered Jan 31 '23 07:01

mdatsev