Как отсортировать ключи объекта в массиве, основываясь на свойствах объекта? - PullRequest
0 голосов
/ 09 мая 2019

У меня есть объект со следующей структурой:

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',
    },
}

В качестве конечного результата мне потребуется получить список ключей:

['ITEM_ONE', 'ITEM_TWO', 'ITEM_THREE']

НО их нужно упорядочить на основе свойства order, что приведет к:

['ITEM_TWO', 'ITEM_ONE', 'ITEM_THREE']

Я предпочитаю использовать библиотеку _lodash для этой цели, но я даже не уверен, какНачнем с него, поскольку структура для root_object является объектом, а не списком.

Ответы [ 6 ]

4 голосов
/ 09 мая 2019

Вы можете сделать это с обычным js, используя метод sort и 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)
2 голосов
/ 09 мая 2019

Просто используйте sort с функцией обратного вызова, например:

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);

Для решения lodash используйте toPairs, sortBy, затем map, чтобы получить ключи:

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>
1 голос
/ 09 мая 2019

Это решение O (n) (sort O (nlogn)), которое работает только для уникальных order значений .

Вы можете использовать lodash для сопоставления значений каждого свойства с порядком ({ ITEM_ONE: 2, ITEM_TWO: 1, ... }), затем инвертировать ключи и значения ({ 1: ITEM_TWO, 2: ITEM_ONE, ... }) и извлекать значения. Это даст вам предметы в правильном порядке :

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>

В vanilla JS путем преобразования объекта в записи сопоставьте записи в виде [order, key], преобразуйте записи в объект с помощью Object.fromEntries() (не поддерживается IE / Edge), а затем получить значения:

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)
1 голос
/ 09 мая 2019

Просто используйте Array.prototype.sort() для массива 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);
1 голос
/ 09 мая 2019

Вы можете отсортировать ключи, взяв значение для сортировки.

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; }
0 голосов
/ 09 мая 2019

Вы можете использовать Object.keys вместе с Array.map и 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)
...