-2

TL;DR

How can I (better) sort an object's properties?

I am not trying to [sort an] object property by values nor its keys.


Issue

I have an object (like the one below) where I need to move properties (key/value pairs) to the beginning of said object.

// Pre-sorted! But can be in any arrangement due to a hidden `channel.live` property
// name: date
{
    // beginning
    "channel-1": "2022-06-29T11:20:14.000Z",
    "channel-2": "2022-06-29T05:58:18.000Z",
    "channel-3": "2022-06-29T05:18:49.000Z",
    "channel-4": "2022-06-29T04:08:35.000Z",
    "channel-5": "2022-06-29T01:52:31.000Z",
    "channel-6": "2022-06-29T01:00:40.000Z",
    "channel-7": "2022-06-29T00:59:47.000Z",
    "channel-8": "2022-06-29T00:07:28.000Z",
    "channel-9": "2022-06-28T23:55:27.000Z",
    // end
}

Tried Solution(s)

The current solution is to delete every other property and re-add them (putting them at the end).

E.g. If I delete channel-5 and re-add it, the object will be stringified (via JSON.stringify) as {"channel-1":"..." ··· "channel-9":"...","channel-5":"..."}, effectively moving the property to the end.

// Prioritize live channels!
// This will move a channel that isn't live to the end of the `Channels` object
if(!channel.live) {
    delete Channels[name];

    Channels[name] = date.toJSON();
}
Ephellon Grey
  • 392
  • 2
  • 9
  • 2
    You should put them into an array. Never assume the order of object properties. – Phaelax z Jun 29 '22 at 14:31
  • I'm not sure that'd work. It'd be simple to just make every channel an object and sort them as they change but, I'm using this logic in an extension with limited storage space. Each byte I can save when saving the object counts – Ephellon Grey Jun 29 '22 at 14:40
  • All you need is Object.entries, Object.fromEntries, Array.sort: ` const obj = {1: '1', 2: '2', 4: '4', 3: '3', 5: '5'}; Object.from(Object.entries(obj).sort(([k1], [k2]) => k1 - k2)) // Returns {1: '1', 2: '2', 3: '3', 4: '4', 5: '5'}` – capchuck Jun 29 '22 at 15:00
  • I'm not sorting by the keys. The keys can be any string value, I just made the data easier to look at – Ephellon Grey Jun 29 '22 at 15:03
  • 1
    So you don't want to sort by the properties or by the values … what do you want to sort by? – Quentin Jun 29 '22 at 15:07
  • I would like to be able to add new properties to the beginning of the object – Ephellon Grey Jun 29 '22 at 15:08
  • @EphellonGrey Why do you even care about the order of properties in your object? Don't do that. If you care about order, use an array. – Bergi Jun 29 '22 at 15:12
  • If you want ordering you could make each key/value an object and put them all inside an array then sort them however you need to - [this](https://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order) may be useful – gratz Jun 29 '22 at 15:17

2 Answers2

0

As you have requirement to delete and add channels as per your conditions i have mention one method to achieve your requirement it should works for you.

let Channels = {
    "channel-1": "2022-06-29T11:20:14.000Z",
    "channel-2": "2022-06-29T05:58:18.000Z",
    "channel-3": "2022-06-29T05:18:49.000Z",
    "channel-4": "2022-06-29T04:08:35.000Z",
    "channel-5": "2022-06-29T01:52:31.000Z",
    "channel-6": "2022-06-29T01:00:40.000Z",
    "channel-7": "2022-06-29T00:59:47.000Z",
    "channel-8": "2022-06-29T00:07:28.000Z",
    "channel-9": "2022-06-28T23:55:27.000Z",
}

if(!channel.live) {
  delete Channels[name];
  Channels[name] = date.toJSON();
}

if(channel.live)
  Channels = { [name]: time.toJSON(), ...Channels };
}

const updatedChannels = {};
Object.keys(Channels).sort().forEach(item => (updatedChannels[item] = Channels[item]));

Channels = updatedChannels;
-1

Copy the darn object...

// Prioritize live channels!
// This will move a channel that is live to the beginning of the `Channels` object
if(channel.live) {
    // Ensures `...Channels` doees NOT overwrite the new property
    delete Channels[name];

    Channels = { [name]: time.toJSON(), ...Channels };
}
Ephellon Grey
  • 392
  • 2
  • 9