0

Please check code bellow:

https://codepen.io/Whity/pen/XWNVqvP?editors=1010;

Result:

[">20Y", {…}]
["5Y", {…}]
["6M", {…}]
["7Y", {…}]
["10Y", {…}]
["14D", {…}]
["15Y", {…}]
["20Y", {…}]

I need to have the element with the '>' symbol last, not first. How can I achieve that?

3 Answers3

0

You could sort by numbers and if a comparison sign is available, then take for the same numerical value the delta of both offsets, which reflects the order of comparison, see my answer with comparison signs.

To get numerical value, just get the digits from the string.

const
    data = [[">20Y", {}], ["5Y", {}], ["6M", {}], ["7Y", {}], ["10Y", {}], ["14D", {}], ["15Y", {}], ["20Y", {}]];

data.sort(([a], [b]) => {
    function getV(s) {
        return {
            value: s.match(/\d+/),
            offset: { '<': -2, '<=': -1, null: 0, '>=': 1, '>': 2 }[s.match(/[<>]={0,1}(?=\s*\d)/)]
        };
    }
    var aa = getV(a),
        bb = getV(b);

    return aa.value - bb.value || aa.offset - bb.offset;
});

console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

When using dictionaries doesn't really make sense to sort by keys, but here you go.

var data = {
  "6M": {},
  "14D": {},
  "7Y": {},
  "10Y": {},
  "5Y": {},
  "15Y": {},
  ">20Y": {},
  "20Y": {}
};

function sortOnKeys(dict) {
    var sorted = [];
    for(var key in dict) {
        sorted[sorted.length] = key;
    }
    sorted.sort(function(a,b) {
        return a.replace(/^\W+/, 'z').localeCompare(b.replace(/^\W+/, 'z'));
    });

    var tempDict = {};
    for(var i = 0; i < sorted.length; i++) {
        tempDict[sorted[i]] = dict[sorted[i]];
    }

    return tempDict;
}

data = sortOnKeys(data);

console.log(data)
jAdex
  • 472
  • 1
  • 5
  • 15
0

Keep it simple. notes are in the comments section in the example.

var obj = {
  "6M": {},
  "14D": {},
  "7Y": {},
  "10Y": {},
  "5Y": {},
  "15Y": {},
  ">20Y": {},
  "20Y": {}
};

//Object.keys() returns an array whose elements are strings corresponding to the enumerable properties found directly upon object

//sort() method sorts the elements of an array in place and returns the sorted array. The default sort order is ascending, built upon converting the elements into strings, then comparing their sequences of UTF-16 code units values.

//reduce() method executes a reducer function (that you provide) on each element of the array, resulting in single output value.


console.log(Object.keys(obj).sort().reduce(function (result, key) {
        result[key] = obj[key];
        return result;
    }, {}));

//just throwing in another variant if you really need numbers to be in right sort order. This  becuase above sort does string comparision. What if comaprision had to be on numaeric base.

console.log(Object.keys(obj).sort((a, b) => a.localeCompare(b, 'en', { numeric: true })));
Syed
  • 696
  • 1
  • 5
  • 11
  • Thank you it works, but what I need is to use Object.entries and forEach (need index). Numbers should be in order - ascending, and '>20Y' should be last. – Rafał Waszak Feb 25 '21 at 10:33
  • thats all good there is an excellent answer with commentary as how to do it ..... https://stackoverflow.com/a/1069840/10588650 – Syed Feb 25 '21 at 16:37
  • just a kind note what you had missed in your original attempt was superficially creating an array just like Object.keys does but for indexing and everything you need Object.fromEntries = The Object.fromEntries() method takes a list of key-value pairs and returns a new object whose properties are given by those entries. It is similar to array from and from there on iterate over how ever you like. yes you will get all indexes and rest of data rows to manipulate as per your liking. – Syed Feb 25 '21 at 16:40
  • idea .... based on above kinked example you could run small regex test on entry point to filter out what string contains '>' pluck it out keep it safe and then add it after whole wort is done. just as I have checked for right at the start of the function https://stackoverflow.com/a/66089035/10588650 – Syed Feb 25 '21 at 16:47