Сортировка без учета регистра с помощью ramda sortWith - PullRequest
0 голосов
/ 02 марта 2020

У меня проблемы с сортировкой глубоко вложенного массива объектов с использованием Ramda sortWith по нескольким столбцам (по возрастанию или по убыванию). Очевидно, сортировка чувствительна к регистру и приводит к тому, что значения, начинающиеся с букв нижнего регистра, помещаются в самый конец отсортированного массива.

Сначала я импортирую необходимые функции ramda:

import { sortWith, path, useWith, split, ascend, descend } from 'ramda'

Затем У меня есть этот массив:

const theList = [
  {
    name: 'A',
    purchase: {
      period: {
        start: '2020-01-08T21:00:00Z',
        end: '3070-10-27T21:00:00Z',
      },
    },
  },
  {
    name: 'b',
    purchase: {
      period: {
        start: '2019-09-30T19:00:00Z',
        end: '3070-10-27T21:00:00Z',
      },
    },
  },
  {
    name: 'C',
    purchase: {
      period: {
        start: '2020-01-26T21:00:00Z',
        end: '3070-10-27T21:00:00Z',
      },
    },
  },
]

Для сортировки у меня есть этот массив с правилами:

const sort = [
  { oder: 'asc', name: 'name' },
  { oder: 'desc', name: 'purchase.period.start' },
]

Наконец, я пытаюсь отсортировать этот массив с заданным набором правил:

const sortFunctions = sort.map(({ order, name }) => (
  (order === 'asc')
    ? ascend(useWith(path, [split('.')])(name))
    : descend(useWith(path, [split('.')])(name))
))

return sortWith(sortFunctions)(theList)

Однако результат таков:

[
  {
    "name": "b",
    "purchase": {
      "period": {
        "start": "2019-09-30T19:00:00Z",
        "end": "3070-10-27T21:00:00Z"
      }
    }
  },
  {
    "name": "C",
    "purchase": {
      "period": {
        "start": "2020-01-26T21:00:00Z",
        "end": "3070-10-27T21:00:00Z"
      }
    }
  },
  {
    "name": "A",
    "purchase": {
      "period": {
        "start": "2020-01-08T21:00:00Z",
        "end": "3070-10-27T21:00:00Z"
      }
    }
  }
]

Таким образом, проблема в том, что b находится не в середине, как ожидалось, потому что он учитывает чувствительность к регистру. Не только это, но и список, по-видимому, также в обратном порядке относительно ожидаемого порядка.

Что я здесь не так делаю и как я могу получить это, чтобы игнорировать регистр?

1 Ответ

1 голос
/ 02 марта 2020

С немного измененной версией вашего кода (используя конвейер, а не useWith, который я предпочитаю избегать, как могу), мы можем добавить toLower внутри компаратора следующим образом:

const makeSorter = compose (
  sortWith,
  map (({order, name}) => (order == 'desc' ? descend : ascend) (
    compose (toLower, path (split ('.', name)))
  ))
)

const sorts = [
  { order: 'asc', name: 'name' },
  { order: 'desc', name: 'purchase.period.start' },
]

// Switched the order to make the sorting clear
const theList = [{name: "C", purchase: {period: {start: "2020-01-26T21: 00: 00Z", end: "3070-10-27T21: 00: 00Z"}}}, {name: "A", purchase: {period: {start: "2020-01-08T21: 00: 00Z", end: "3070-10-27T21: 00: 00Z"}}}, {name: "b", purchase: {period: {start: "2019-09-30T19: 00: 00Z", end: "3070-10-27T21: 00: 00Z"}}}]

console .log (
  makeSorter (sorts) (theList)
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>
<script> const {compose, sortWith, map, ascend, descend, toLower, path, split} = R </script>

Я также изменил тест с asc на desc, потому что я работал с чем-то похожим, где asc было значением по умолчанию, а поле было необязательный. (desc был обязательным, когда это было необходимо.)

Это просто позволяет избежать некоторого повторения функций, которые мы передаем ascend или descend:

    (order == 'desc' ? descend : ascend)

У меня нет Проверено, что это действительно работает для нескольких сортировок, так как все значения не совпадают с именем, но похоже, что оно должно работать.

...