简体   繁体   中英

Sort an object by an optional field without losing the keys

I've got the following object which I'd like to sort by its priority fields.

{
    anchor_block: {
        label: 'Anker-Block',
        priority: 100,
        description: ...,
        fields: ...
    },
    categories_block: {
        label: 'Categories-Block',
        description: ...,
        fields: ...
    },
    contact_block: {
        label: 'Kontakt-Block',
        description: ...,
        fields: ...
    },
    employee_block: {
        label: 'Mitarbeiter-Block',
        priority: 90,
        description: ...,
        fields: ...
    }
}

I've tried to sort them with lodash:

_.orderBy(blocks, ['priority'], ['desc']);

But this solution removes the all the keys from my objects (because it returns an array) and it also puts the ones without a priority field on top:

[
    {
        label: 'Categories-Block',
        description: ...,
        fields: ...
    },
    {
        label: 'Kontakt-Block',
        description: ...,
        fields: ...
    },
    {
        label: 'Anker-Block',
        priority: 100,
        description: ...,
        fields: ...
    },
    {
        label: 'Mitarbeiter-Block',
        priority: 90,
        description: ...,
        fields: ...
    },
]

Does any one of you have an idea on how to solve this with lodash? I'd like to avoid iterating it myself, because I'm sure it's possible, I just don't get my head around it.

Updated Answer: Approach is to store all keys, sort them according to the order you desire, and then use those keys to retrieve values from the original object in desired order.

let obj = {
    anchor_block: {
        label: 'Anker-Block',
        priority: 100,
        description: '...',
        fields: '...'
    },
    categories_block: {
        label: 'Categories-Block',
        description: '...',
        fields: '...'
    },
    contact_block: {
        label: 'Kontakt-Block',
        description: '...',
        fields: '...'
    },
    employee_block: {
        label: 'Mitarbeiter-Block',
        priority: 90,
        description: '...',
        fields: '...'
    }
}
/*
    Plain JS, no Lodash
*/

let sortedKeys = Object.keys(obj);
sortedKeys.sort((key1, key2) => {
    let p1 = obj[key1].priority || 0, p2 = obj[key2].priority || 0;
    if(p1<p2)
        return 1; // Put key2 first in sorted order
    return -1; // Else, put key1 first in sorted order
    /*
        For ascending order, do this
        if(p1<p2)
            return -1;
        return 1;
    */
})

sortedKeys.forEach(key => {
    console.log(key,"-->",obj[key]);
})

Output

anchor_block --> { label: 'Anker-Block',
  priority: 100,
  description: '...',
  fields: '...' }
employee_block --> { label: 'Mitarbeiter-Block',
  priority: 90,
  description: '...',
  fields: '...' }
categories_block --> { label: 'Categories-Block', description: '...', fields: '...' }
contact_block --> { label: 'Kontakt-Block', description: '...', fields: '...' }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM