Лучший способ переупорядочить массив объектов?

У меня есть массив или объект, который будет служить столбцом для таблицы с уникальным ключом.

const list = [{
    key: "Name",
    textColor: "red"
  },{
    key: "Age",
    textColor: "green"
  },{
    key: "Occupation",
    textColor: "yellow"
}]

И у меня есть список упорядочения столбцов в таблице

const newOrder = ["Occupation", "Name", "Age"]

Теперь, как я могу изменить список в соответствии с newOrder без использования nested loops. Кроме того, все они являются динамическими, поэтому речь идет не только о вышеупомянутых трех столбцах.

Ожидаемый результат

const list = [{
    key: "Occupation",
    textColor: "yellow"
  },{
    key: "Name",
    textColor: "red"
  },{
    key: "Age",
    textColor: "green"
}]

могут ли быть элементы с повторяющимся ключом

cmgchess 16.03.2022 14:58

На данный момент порядок сортировки в обратном алфавитном порядке. О, Н, А. Так будет всегда?

Andy 16.03.2022 15:10
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
2
76
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Вы можете использовать Сортировать по из библиотеки lodash

Ответ принят как подходящий

Ваш список можно переформатировать в обычный объект javascript, в котором key — это имя свойства, а textColor — это значение:

const toObject = kvps => Object.fromEntries(kvps.map(kvp => [ kvp.key, kvp.textColor ]));

С заданным массивом ключей вы можете выбирать значения из этого объекта следующим образом:

const fromObject = (order, obj) => order.map(key => ({ key, textColor: obj[key] }));

Соедините их вместе, и вы можете изменить порядок любого списка пар ключ-значение:

const list = [{
    key: "Name",
    textColor: "red"
  },{
    key: "Age",
    textColor: "green"
  },{
    key: "Occupation",
    textColor: "yellow"
}]


const toObject = kvps => Object.fromEntries(kvps.map(kvp => [ kvp.key, kvp.textColor ]));
const fromObject = (order, obj) => order.map(key => ({ key, textColor: obj[key] }));
const reorder = (order, kvps) => fromObject(order, toObject(kvps));


const newList = reorder(["Occupation", "Name", "Age"], list);

console.info(
  newList
)

Edit: if the sizes of your list and order arrays are small, you probably want to go with the much easier to read approach suggested by Jon Webb in one of the other answers. ? I tried to keep my solution to an O(n + m) complexity rather than O(n * m), (n = list size, m = order size) but it's probably not worth the added complexity.

Это менее сложное решение, которое я искал.

Chandrika 16.03.2022 15:43

Вы можете выполнить итерацию по списку "заказ", найдя соответствующий элемент в исходном списке, и поместить элемент в новый список в указанном порядке:

const orderList = (list, order) => {
  const newList = [];

  for (key of order) {
    const item = list.find((obj) => obj.key == key);
    if (item) newList.push(item);
  }

  return newList;
}

Вы можете использовать метод sort для массива. Метод sort будет сортировать на месте, поэтому вам следует скопировать свой массив, если вы не хотите изменять оригинал.

Метод массива sort принимает функцию сравнения, которая получает два элемента для сравнения a и b. Он должен возвращать число и сортировать их в зависимости от этого числа:

  • Если > 0, то b стоит перед a
  • Если < 0, то b стоит после a
  • Если 0 то оставить как есть

Используя indexOf в массиве newOrder, можно получить индекс ключа. И индекс 0 должен идти раньше, и индекс 1 должен идти раньше, и индекс 2, конечно. Итак, если индекс a.key равен 2, а индекс b.key равен 0, то мы должны вернуть значение больше 0, поскольку b должно стоять перед a.

В моей реализации ниже я клонирую исходный список ([...list]), чтобы случайно не мутировать. С тем же успехом вы могли бы сделать list.sort(...), если вам не нужно или не нужно мутировать.

const list = [{
    key: "Name",
    textColor: "red"
  },{
    key: "Age",
    textColor: "green"
  },{
    key: "Occupation",
    textColor: "yellow"
}]

const newOrder = ["Occupation", "Name", "Age"]

function sort(list, order) {
  return [...list].sort((a, b) => {
    const keyIndexA = order.indexOf(a.key);
    const keyIndexB = order.indexOf(b.key);
    if (keyIndexA < keyIndexB) return -1;
    if (keyIndexA > keyIndexB) return 1;
    return 0;
  });
}

console.info(sort(list, newOrder));

Вы можете использовать обычный Сортировать

const list = [{key: "Name",textColor: "red"},{key: "Age",textColor: "green"},{key: "Occupation",textColor: "yellow"}];
const newOrder = ["Occupation", "Name", "Age"];

const result = list.sort(({key: a}, {key: b}) => newOrder.indexOf(a) - newOrder.indexOf(b));

console.info(result);
.as-console-wrapper{min-height: 100%!important; top: 0}

обратите внимание, что sort выполняет сортировку на месте, нет необходимости назначать новую переменную

gftea 16.03.2022 15:49

Вы можете попробовать перебрать массив newOrder, найти объект, который соответствует первому элементу, и нажать на новый массив.

const orderedList = [];
newOrder.forEach(order => {
    orderedList.push(list.find(({key}) => key === order));
})

Другие вопросы по теме