4

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.

3 Answers 3

7

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.

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you for your answer, I'm having trouble now with writing my sort methods for ascending and descending. Would you possibly be able to add this to your answer? I know you omitted it but not sure what I'm doing wrong
Do you want to sort by the date or by the item1 for example?
I know it's cheeky but if you wouldn't mind doing date and item1 that would be amazing. I'm not sure what I've done wrong. Thank you again!
Ok i edited it so now it sorts by whatever key you pass to the function.
Hello, this is working fine for only the value is numeric, is there any way that we can sort if the value is string? for eg. let unsorted_data = { "2010-01": { "item1": "[V11]Encore Sandstone V11" ...... please help.
2

This approach uses Arrow functions and reduce function.

It's a little shorter.

let 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 } };
// ----------------
let byThis = 'item1';
let compare = (k, kk) => data[k][byThis] - data[kk][byThis];

let sorted = Object.keys(data).sort(compare).reduce((a, d) => ({ ...a, ...{ [d]: data[d] } }), {});

console.log(sorted);
.as-console-wrapper {
  max-height: 100% !important
}

Comments

0

I had the same problem. I made the mistake of storing two combined arrays in a string and then trying to use the sort method. Try this:

if (charSelected == "all") 
    {
        charArray = heroes.concat(villains).sort();

    }

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.