skip to Main Content

I can’t sort a list of key/value pairs in an object in natural order when a leading zero precedes a 4-digit key.

This is the object with key/value pairs:

plain_options = { 
"1001":"Freizeile",
"1101":"Freizeile",
"1201":"Zwischenmahlzeit",
"1301":"Zwischenmahlzeit",
"0101":"Frühstück",
"0201":"Freizeile",
"0301":"Freizeile",
"0401":"Menü A",
"0501":"Menü B",
"0601":"Freizeile",
"0701":"Freizeile",
"0801":"Mittag 1",
"0901":"Mittag 2"
}

and i get this what is correct

sorted_options_parse_int = {
"0101":"Frühstück",
"0201":"Freizeile",
"0301":"Freizeile",
"0401":"Menü A",
"0501":"Menü B",
"0601":"Freizeile",
"0701":"Freizeile",
"0801":"Mittag 1",
"0901":"Mittag 2",
"1001":"Freizeile",
"1101":"Freizeile",
"1201":"Zwischenmahlzeit",
"1301":"Zwischenmahlzeit"
}

with following code:


function sortObjectByKeyParseInt(obj) {
    const sortedKeys = Object.keys(obj).sort((a, b) => parseInt(a, 10) - parseInt(b, 10));
     const sortedObj = {};
     sortedKeys.forEach(key => {
         sortedObj[key] = obj[key];
    });
    return sortedObj;
}

var sorted_options_parse_int = sortObjectByKeyParseInt(plain_options);
console.log('ParseInt: ', sorted_options_parse_int);

options = '';
Object.entries(sorted_options_parse_int).forEach((item) => {
 console.log('Item: ', item);
 options += '<option value="'+item[0]+'"><b>'+item[1]+'</b></option>';
});

but if loop over the object with forEach the sorting is different.

"Item: ", ["1001", "Freizeile"]
"Item: ", ["1101", "Freizeile"]
"Item: ", ["1201", "Zwischenmahlzeit"]
"Item: ", ["1301", "Zwischenmahlzeit"]
"Item: ", ["0101", "Frühstück"]
"Item: ", ["0201", "Freizeile"]
"Item: ", ["0301", "Freizeile"]
"Item: ", ["0401", "Menü A"]
"Item: ", ["0501", "Menü B"]
"Item: ", ["0601", "Freizeile"]
"Item: ", ["0701", "Freizeile"]
"Item: ", ["0801", "Mittag 1"]
"Item: ", ["0901", "Mittag 2"]
}

What is the problem why i get the 1001,1101,1201,1301 before the 0101,0201….
The keys are always numeric, with 4 digits and leading zeros.
How can i resolve this?

I searched for a solution but find nothing, which point to this.

Many Thanks

EDIT:

I discovered that the problem is later in my code. I’m iterating over the generated object with forEach, it seems the sorting is interpreted differently in the forEach loop.
Updated the Question and create a fiddle.
Here is the fiddle: https://jsfiddle.net/gh5kt310/

2

Answers


  1. parseInt() removes the leading 0

    Login or Signup to reply.
  2. Keys are numeric strings. Therefore, they cannot be sorted correctly. If the keys are converted to numbers, the problem is solved as follows :

    let plain_options = {
      "1001":"Freizeile",
      "1101":"Freizeile",
      "1201":"Zwischenmahlzeit",
      "1301":"Zwischenmahlzeit",
      "0101":"Frühstück",
      "0201":"Freizeile",
      "0301":"Freizeile",
      "0401":"Menü A",
      "0501":"Menü B",
      "0601":"Freizeile",
      "0701":"Freizeile",
      "0801":"Mittag 1",
      "0901":"Mittag 2"
    }
    function sortObjectByKeyParseInt(input) {
      const ordered = Object.keys(input).sort().reduce(
        (obj, key) => {
          obj[+key] = input[key];
          return obj;
        },
        {}
      );
      return ordered
    }
    
    const sorted_options_parse_int = sortObjectByKeyParseInt(plain_options);
    console.log('ParseInt: ', sorted_options_parse_int);
    

    output is :

    {
      "101": "Frühstück",
      "201": "Freizeile",
      "301": "Freizeile",
      "401": "Menü A",
      "501": "Menü B",
      "601": "Freizeile",
      "701": "Freizeile",
      "801": "Mittag 1",
      "901": "Mittag 2",
      "1001": "Freizeile",
      "1101": "Freizeile",
      "1201": "Zwischenmahlzeit",
      "1301": "Zwischenmahlzeit"
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search