Reputation: 1886
I have an object with the following structure:
root_object: {
ITEM_ONE: {
order: 2,
prop_one: '123',
prop_two: '456',
},
ITEM_TWO: {
order: 1,
prop_one: '789',
prop_two: '321',
},
ITEM_THREE: {
order: 3,
prop_one: '654',
prop_two: '987',
},
}
As an end result, I will need to get the list of keys:
['ITEM_ONE', 'ITEM_TWO', 'ITEM_THREE']
BUT they need to be ordered based on the property order
, which will result as:
['ITEM_TWO', 'ITEM_ONE', 'ITEM_THREE']
I prefer to use the _lodash
library for this purpose, but I'm not even sure how to start with it, since the structure for the root_object
is an object and not a list.
Upvotes: 0
Views: 70
Reputation: 191996
This is an O(n) solution (sort is O(nlogn)) that works only for unique order
values.
You can use lodash to map the values of each property to the order ({ ITEM_ONE: 2, ITEM_TWO: 1, ... }
), then invert the keys and values ({ 1: ITEM_TWO, 2: ITEM_ONE, ... }
), and extract the values. This will get you the items in the right order:
const { flow, partialRight: pr, mapValues, invert, values } = _
const fn = flow(
pr(mapValues, 'order'), // convert to { ITEM_ONE: 2, ITEM_TWO: 1, ... }
invert, // convert to { 1: ITEM_TWO, 2: ITEM_ONE, ... }
values // get the array of keys
)
const root_object = {"ITEM_ONE":{"order":2,"prop_one":"123","prop_two":"456"},"ITEM_TWO":{"order":1,"prop_one":"789","prop_two":"321"},"ITEM_THREE":{"order":3,"prop_one":"654","prop_two":"987"}}
const result = fn(root_object)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
In vanilla JS by convert the object to entries, map the entries to the form of [order, key]
, convert the entries to object with Object.fromEntries()
(not supported by IE/Edge), and then get the values:
const fn = o => Object.values(Object.fromEntries(
Object.entries(o).map(([k, { order }]) => [order, k])
))
const root_object = {"ITEM_ONE":{"order":2,"prop_one":"123","prop_two":"456"},"ITEM_TWO":{"order":1,"prop_one":"789","prop_two":"321"},"ITEM_THREE":{"order":3,"prop_one":"654","prop_two":"987"}}
const result = fn(root_object)
console.log(result)
Upvotes: 1
Reputation: 1679
You can use Object.keys
along with Array.map
and Array.sort
const root_object = {
ITEM_ONE: {
order: 2,
prop_one: '123',
prop_two: '456',
},
ITEM_TWO: {
order: 1,
prop_one: '789',
prop_two: '321',
},
ITEM_THREE: {
order: 3,
prop_one: '654',
prop_two: '987',
},
}
let rootArr = [];
let sortedRootObject = Object.keys(root_object).map(key => rootArr.push(root_object[key])).sort((a, b) => rootArr[b.order] - rootArr[a.order])
console.log(sortedRootObject)
Upvotes: 0
Reputation: 149030
Just use sort
with a callback function, like so:
var root = {ITEM_ONE:{order:2,prop_one:'123',prop_two:'456'},ITEM_TWO:{order:1,prop_one:'789',prop_two:'321'},ITEM_THREE:{order:3,prop_one:'654',prop_two:'987'}};
var keys = Object.keys(root).sort((a, b) => root[a].order - root[b].order);
console.log(...keys);
For a lodash solution, use toPairs
, sortBy
, then map
to get the keys:
var root = {ITEM_ONE:{order:2,prop_one:'123',prop_two:'456'},ITEM_TWO:{order:1,prop_one:'789',prop_two:'321'},ITEM_THREE:{order:3,prop_one:'654',prop_two:'987'}};
console.log(..._.map(_.sortBy(_.toPairs(root), '1.order'), 0));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
Upvotes: 2
Reputation: 56753
Just use Array.prototype.sort()
on the array of Object.keys(root_object)
:
const root_object = {
ITEM_ONE: {
order: 2,
prop_one: '123',
prop_two: '456',
},
ITEM_TWO: {
order: 1,
prop_one: '789',
prop_two: '321',
},
ITEM_THREE: {
order: 3,
prop_one: '654',
prop_two: '987',
},
}
let result = Object.keys(root_object).sort((a,b) => root_object[a].order - root_object[b].order);
console.log(result);
Upvotes: 1
Reputation: 122057
You can do this with plain js using sort
method and Object.keys
.
const data = {"ITEM_ONE":{"order":2,"prop_one":"123","prop_two":"456"},"ITEM_TWO":{"order":1,"prop_one":"789","prop_two":"321"},"ITEM_THREE":{"order":3,"prop_one":"654","prop_two":"987"}}
const res = Object.keys(data).sort((a, b) => data[a].order - data[b].order)
console.log(res)
Upvotes: 4
Reputation: 386654
You could sort the keys by taking the value for sorting.
var object = { root_object: { ITEM_ONE: { order: 2, prop_one: '123', prop_two: '456' }, ITEM_TWO: { order: 1, prop_one: '789', prop_two: '321' }, ITEM_THREE: { order: 3, prop_one: '654', prop_two: '987' } } },
keys = Object.keys(object.root_object);
keys.sort((a, b) => object.root_object[a].order - object.root_object[b].order);
console.log(keys);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1