1

This is my code I have successfully sorted and got my final result to be what I wanted. Now I want to also sort so that the object name that contains the key word "newitem" will always get sorted to the bottom.

    var testgogo = {
      "newitemwrewt": {
        "brand": {
          "gdhshd": true
        },
        "stock": 2,
        "sold": 3
      },
      "other": {
        "brand": {
          "gdhshd": true
        },
        "stock": 2,
        "sold": 3
      },
      "newitemncnc": {
        "brand": {
          "gdhshd": true
        },
        "stock": 2,
        "sold": 3
      },
    };
    finalresult = Object
      .keys(testgogo)
      .sort(
        (a, b) =>
        (testgogo[a].stock !== undefined) - (testgogo[b].stock !== undefined) 
 || testgogo[a].stock - testgogo[b].stock 
|| testgogo[b].sold - testgogo[a].sold )[0];
    console.log(finalresult);

Thanks for any help

Tosps
  • 73
  • 7
  • 1
    Possible duplicate of [Does JavaScript Guarantee Object Property Order?](https://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order) – isherwood May 17 '19 at 16:37
  • ^ Worth noting that while relevant, object order **is** guaranteed now. Though most of the better answers on those delve into that a bit. – Tyler Roper May 17 '19 at 16:37
  • I used Object.keys in my code. how do I sort them so key names that contain the word "newitem" should always go to bottom? thanks – Tosps May 17 '19 at 17:42

2 Answers2

1

Javascript objects can't be ordered. If you need that data to be in an order you should make it an array.

cullanrocks
  • 457
  • 4
  • 16
  • 3
    This is not true anymore, though I agree with it in practice. – Tyler Roper May 17 '19 at 16:37
  • Hmm interesting. I guess it's just not a great habit to get into though. This is why we have mapping and filtering functions. – cullanrocks May 17 '19 at 16:41
  • I used Object.keys in my code. how do I sort them so key names that contain the word "newitem" should always go to bottom? thanks – Tosps May 17 '19 at 17:39
0

You could sort the entries of the object based on whether the key includes the string "newitem". Then use Object.fromEntries() to convert the sorted entries back to an object

const testgogo={newitemfgre:{brand:{gdhshd:!0},stock:2,sold:3},fruit:{brand:{grgrdgdr:!0,ggyugy:!0},stock:3,sold:2},vegetable:{brand:{htrhtr:!0},stock:1,sold:1},newitemwrewt:{brand:{gdhshd:!0},stock:2,sold:3},other:{brand:{gdhshd:!0},stock:2,sold:3},newitemncnc:{brand:{gdhshd:!0},stock:2,sold:3},snack:{brand:{htrhr:!0},stock:1,sold:4},afga:{brand:{gdhshd:!0},stock:1,sold:2},other:{brand:{gdhshd:!0},stock:2,sold:3}};

const str = "newitem";

const sortedEntries = Object.entries(testgogo)
              .sort((a, b) => a[0].includes(str) - b[0].includes(str));
      
const output = Object.fromEntries(sortedEntries)

console.log(output)

Subtracting booleans returns a 1, -1 or 0.

true - false === 1
false - true === -1
true - true === 0

So, if a[0] has "newitem" but b[0] doesn't, the key at a[0] will be moved to the end of the entries array.

adiga
  • 34,372
  • 9
  • 61
  • 83
  • can you use object.keys to do this? I used object.keys in my code, how do I sort them so key names that contain the word "newitem" should always go to bottom? thanks – Tosps May 17 '19 at 17:41
  • when testing this code at this site https://www.webtoolkitonline.com/javascript-tester.html , the console log shows the object names contain "newitem" still don't go to bottom – Tosps May 17 '19 at 17:57
  • @Tosps `Object.keys` creates an array of keys `[key1, key2, ..]` etc while `Object.entries` creates an array of key-value tuples. `[ [key1, value1], [key2, value2]... ]`. This is why I use `a[0].includes`. If you have keys `Object.keys(testgogo) .sort((a, b) => a.includes(str) - b.includes(str))` This just gives an array of sorted keys – adiga May 17 '19 at 17:57
  • The advantage with `Object.entries` is that you can just use `Object.fromEntries` to convert it back to an object. With array of keys, you'd have to `reduce` the sorted keys to create an object. – adiga May 17 '19 at 17:58
  • @Tosps it works fine in the snippet. By the way, it won't modify the original object, it will create a new object. – adiga May 17 '19 at 17:58
  • Thanks I added ||a.includes(str) - b.includes(str) to my code, it worked in console log – Tosps May 17 '19 at 18:06
  • @Tosps you're welcome. Please upvote and [accept the answer](https://meta.stackexchange.com/a/5235/289255) – adiga May 17 '19 at 18:08