Сортировка нескольких строк данных в JavaScript с помощью lodash - PullRequest
0 голосов
/ 04 сентября 2018

У меня есть некоторые данные, которые я хочу отсортировать в таблицу. Данные состоят из массива строк, которые в свою очередь являются массивами ячеек, которые являются объектами со свойствами column_name, column_value, column_type и column_id (как показано ниже).

Я хотел бы отсортировать данные по нескольким столбцам, например, Я хотел бы отсортировать по city по возрастанию, а затем по age по убыванию. Я считаю, что lodash _.orberBy() может достичь этого, но я не могу понять, как реализовать это на вложенных данных, как это.

Хотя я подозреваю, что lodash выполнит свою работу, я подозреваю, что может быть другой способ, который лучше.

Как мне отсортировать следующие вложенные данные по разным столбцам?

import _ from 'lodash';

const sampleData = [
  [
    {
      column_name: 'id',
      column_value: '12345',
      column_type: 'string',
      column_id: 'item_attributes#id',
    },
    {
      column_name: 'age',
      column_value: '32',
      column_type: 'number',
      column_id: 'item_attributes#age',
    },
    {
      column_name: 'city',
      column_value: 'London',
      column_type: 'string',
      column_id: 'item_attributes#city',
    },
  ],
  [
    {
      column_name: 'id',
      column_value: 'abcde',
      column_type: 'string',
      column_id: 'item_attributes#id',
    },
    {
      column_name: 'age',
      column_value: '52',
      column_type: 'number',
      column_id: 'item_attributes#age',
    },
    {
      column_name: 'city',
      column_value: 'Bristol',
      column_type: 'string',
      column_id: 'item_attributes#city',
    },
  ],
  [
    {
      column_name: 'id',
      column_value: 'a1b2d',
      column_type: 'string',
      column_id: 'item_attributes#id',
    },
    {
      column_name: 'age',
      column_value: '21',
      column_type: 'number',
      column_id: 'item_attributes#age',
    },
    {
      column_name: 'city',
      column_value: 'London',
      column_type: 'string',
      column_id: 'item_attributes#city',
    },
  ],
];

const orderedData = _.orderBy(
  sampleData,
  // ?? what goes here?
  // ?? what goes here?
);

// desired output
// [
//   [
//     {
//       column_name: 'id',
//       column_value: 'abcde',
//       column_type: 'string',
//       column_id: 'item_attributes#id',
//     },
//     {
//       column_name: 'age',
//       column_value: '52',
//       column_type: 'number',
//       column_id: 'item_attributes#age',
//     },
//     {
//       column_name: 'city',
//       column_value: 'Bristol',
//       column_type: 'string',
//       column_id: 'item_attributes#city',
//     },
//   ],
//   [
//     {
//       column_name: 'id',
//       column_value: '12345',
//       column_type: 'string',
//       column_id: 'item_attributes#id',
//     },
//     {
//       column_name: 'age',
//       column_value: '32',
//       column_type: 'number',
//       column_id: 'item_attributes#age',
//     },
//     {
//       column_name: 'city',
//       column_value: 'London',
//       column_type: 'string',
//       column_id: 'item_attributes#city',
//     },
//   ],
//   [
//     {
//       column_name: 'id',
//       column_value: 'a1b2d',
//       column_type: 'string',
//       column_id: 'item_attributes#id',
//     },
//     {
//       column_name: 'age',
//       column_value: '21',
//       column_type: 'number',
//       column_id: 'item_attributes#age',
//     },
//     {
//       column_name: 'city',
//       column_value: 'London',
//       column_type: 'string',
//       column_id: 'item_attributes#city',
//     },
//   ],
// ]

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

Я думаю, что это должно делать то, что вам нужно. Проще всего преобразовать каждую строку в более приятный объект, прежде чем пытаться использовать lodash для сортировки, но мы можем сделать это как часть функции orderBy lodash:

const sampleData = [
  [
    {
      column_name: 'id',
      column_value: '12345',
      column_type: 'string',
      column_id: 'item_attributes#id',
    },
    {
      column_name: 'age',
      column_value: '32',
      column_type: 'number',
      column_id: 'item_attributes#age',
    },
    {
      column_name: 'city',
      column_value: 'London',
      column_type: 'string',
      column_id: 'item_attributes#city',
    },
  ],
  [
    {
      column_name: 'id',
      column_value: 'abcde',
      column_type: 'string',
      column_id: 'item_attributes#id',
    },
    {
      column_name: 'age',
      column_value: '52',
      column_type: 'number',
      column_id: 'item_attributes#age',
    },
    {
      column_name: 'city',
      column_value: 'Bristol',
      column_type: 'string',
      column_id: 'item_attributes#city',
    },
  ],
  [
    {
      column_name: 'id',
      column_value: 'a1b2d',
      column_type: 'string',
      column_id: 'item_attributes#id',
    },
    {
      column_name: 'age',
      column_value: '21',
      column_type: 'number',
      column_id: 'item_attributes#age',
    },
    {
      column_name: 'city',
      column_value: 'London',
      column_type: 'string',
      column_id: 'item_attributes#city',
    },
  ],
];

const rowToNiceObject = row => row.reduce((prev, curr) => {
  const thisKey = curr['column_name'];
  const thisValue = curr['column_value'];
  
  const newObject = {};
  newObject[thisKey] = thisValue;
  
  return Object.assign(prev, newObject);
}, {});

const result = _.orderBy(sampleData, [
  row => rowToNiceObject(row).city,
  row => rowToNiceObject(row).age
], [
  'asc',
  'desc'
]);

console.dir(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
0 голосов
/ 04 сентября 2018

Лично я думаю, что вам следует немного отобразить структуру данных, чтобы она лучше подходила для операций JavaScript, таких как { id: '12345', age: 32, city: 'London'}. Значения могут содержать тип.

Однако, с вашей текущей структурой данных вы можете сделать сортировку следующим образом:

const orderedData = _.orderBy(
  sampleData,
  entry => entry.find(valueObj => valueObj.column_name==='age').column_value
);

В этом примере используется ваше свойство 'age'. Он работает, находя запись в массиве вашей коллекции объектов, получая имя, описывающее возраст, а затем сравнивая по этому столбцу.

Замена на 'city' или 'id' работает нормально.

...