-1

I currently have an object array which I sort and reduce like so: (The reason I used the below is that I found it in a post sort by alphabetical order keys in js)

    const sortedData = Object.entries(templateData)
      .sort(([,v1], [,v2]) => +v2 - +v1)
      .reduce((r, [k, v]) => ({ ...r, [k]: v }), {});

This produces the following on a console.log(sortedData)

Aguascalientes
: 
{productTemplate: {…}, colorVariants: false}
Alabama
: 
{productTemplate: {…}, colorVariants: false}
Alaska
: 
{productTemplate: {…}, colorVariants: false}
Arizona
: 
{productTemplate: {…}, colorVariants: false}
Arizona 
: 
{productTemplate: {…}, colorVariants: false}
Arkansas
: 
{productTemplate: {…}, colorVariants: false}

This is exactly what I want. However the list still appears as if it's NOT in alphabetical order.

When I do a forEach right after the above code like so:

    Object.keys(sortedData).forEach((element, idx) => {
      console.log(element)
      console.log(idx)
    });

The list appears in it's original order NOT the sorted reduced one. What am I missing here?

FabricioG
  • 3,107
  • 6
  • 35
  • 74
  • 1
    You can't control the order of properties in an object, that's controlled by the way the runtime works. Why do you even want to? You can pull out the name/value pairs in an array (as you do) and then sort the array however you want. – Pointy Feb 16 '23 at 23:30
  • @Pointy Except for numeric keys, they're supposed to retain insertion order. – Barmar Feb 16 '23 at 23:36
  • @Barmar well yea, true, but there are rules for all keys. As far as I can tell the code above is trying to sort by values, numeric ones? Which I don't see in the posted results, so I can't say exactly what's going on. The bottom line is that one of my life rules is to not rely on property ordering in JavaScript because it's fragile. – Pointy Feb 16 '23 at 23:37
  • Yeah, something is weird. The code is sorting numerically, but the question refers to alphabetical order. – Barmar Feb 16 '23 at 23:39
  • There's a bunch of code here that "hides" what the original data is. If your templateData is well behaved, we shouldn't need those `+`, for example. Also, protip: don't skimp on your var names. Even if today you know that `v` is a value, `k` is a key, etc, that tells others nothing about what your code does. Including "three months from now" you, just use variables that actually describe what the data is rather than single letters, the JS engine doesn't care but humans do _so very much_ =) – Mike 'Pomax' Kamermans Feb 16 '23 at 23:41
  • I found this answer in a "sort by alphabetical order keys" post so I applied it to this. @Mike'Pomax'Kamermans – FabricioG Feb 16 '23 at 23:42
  • Cool: if you use someone else's code, always adapt it to your use-case. _Especially_ if you found it on Stackoverflow =) – Mike 'Pomax' Kamermans Feb 16 '23 at 23:43
  • Never mind that last comment. I just figured out that the `reduce()` is just doing what `Object.fromEntries()` does (I was about to post an answer saying they need to use that). – Barmar Feb 16 '23 at 23:43
  • Does this answer your question? [Does JavaScript guarantee object property order?](https://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order) – pilchard Feb 16 '23 at 23:44
  • @Barmar is the sort and reduce the method I should even be using to alphabetize an array of objects? – FabricioG Feb 16 '23 at 23:44
  • 1
    Having said that: can you turn this into an [mcve]? That is, show some "dummy" input data that has the same problem so that folks don't need to guess at what you started with (the data you're showing in your post can't actually be used to reproduce the problem). – Mike 'Pomax' Kamermans Feb 16 '23 at 23:45
  • You can use `Object.fromEntries()` instead of `reduce`. – Barmar Feb 16 '23 at 23:45
  • But you aren't sorting an array of objects, you're trying to sort object properties – pilchard Feb 16 '23 at 23:45
  • If you want to sort an array of objects you don't need reduce at all, just sort. – Barmar Feb 16 '23 at 23:46
  • @Barmar ok got it let me try that. – FabricioG Feb 16 '23 at 23:47

1 Answers1

1

You can use a transient Map that ensures key order based on insertion :

const data = {
  a: 5,
  b: 3,
  c: 8,
  d: 1
};

console.log(data);

const m = new Map([...Object.entries(data)].sort((a, b) => +b[1] - +a[1]));

console.log(Object.fromEntries(m.entries()));
Bertrand
  • 1,840
  • 14
  • 22