Как отсортировать массив объектов на основе заданного отсортированного массива, содержащего значения с помощью Lodash? - PullRequest
0 голосов
/ 10 июня 2019

Используя Lodash, как мне отсортировать массив объектов на основе заданного отсортированного массива, содержащего значения?

Например, дано:

const movies = [
    {
        title: "La La Land",
        genre: "Musical"
    },
    {
        title: "Avengers",
        genre: "Action"
    },
    {
        title: "Chucky",
        genre: "Horror"
    }
]

const titles = [
    "Chucky",
    "La La Land",
    "Avengers"
]

Как мне получить:

const sortedMovies = [
    {
        title: "Chucky",
        genre: "Horror"
    },
    {
        title: "La La Land",
        genre: "Musical"
    },
    {
        title: "Avengers",
        genre: "Action"
    }
]

, который сортируется по порядку сортировки названий фильмов из массива titles?

Ответы [ 3 ]

0 голосов
/ 10 июня 2019

Вам может не понадобиться lodash для этого.Пожалуйста, проверьте, полезно ли ниже soln или нет.

const movies = [
  {
    title: "La La Land",
    genre: "Musical"
  },
  {
    title: "Avengers",
    genre: "Action"
  },
  {
    title: "Chucky",
    genre: "Horror"
  }
];

const titles = ["Chucky", "La La Land", "Avengers"];
const orderMap = titles.reduce((acc, data, index) => {
  acc[data] = titles.length - index;
  return acc;
}, {});
x = movies.sort((x, y) => {
  const orderOfX = titles.length - orderMap[x.title];
  const orderOfY = titles.length - orderMap[y.title];
  return orderOfX - orderOfY;
});
console.log(x);
0 голосов
/ 11 июня 2019

Вы можете просто проверить с помощью Array.indexOf индекс и сравнить с помощью Array.sort .Для этого не нужно использовать lodash:

const movies = [{"title":"La La Land","genre":"Musical"},{"title":"Avengers","genre":"Action"},{"title":"Chucky","genre":"Horror"}]
const titles = ["Chucky","La La Land","Avengers"]

let result = movies.sort((a,b) => titles.indexOf(a.title) - titles.indexOf(b.title))

console.log(result)

Если вы не имеете дело с сотнями тысяч записей в этих массивах, производительность не должна быть проблемой.Однако, если вам нужен высокопроизводительный, вы можете сделать это путем сокращения до простой пары key/value, где ваш ключ - string, а значение index in the array:

const movies = [{"title":"La La Land","genre":"Musical"},{"title":"Avengers","genre":"Action"},{"title":"Chucky","genre":"Horror"}]
const titles = ["Chucky","La La Land","Avengers"]
  .reduce((acc,c,i) => (acc[c] = i, acc), {}) // reduce to a key/value pairs

let result = movies.sort((a,b) => titles[a.title] - titles[b.title]) // sort by index

console.log(result)
0 голосов
/ 10 июня 2019

Создайте Map (titlesByOrder) из titles, где ключом является заголовок, а значением является индекс из исходного массива. Затем используйте _.sortBy() и в обратном вызове верните значение текущего заголовка из объекта titlesByOrder:

const movies = [{"title":"La La Land","genre":"Musical"},{"title":"Avengers","genre":"Action"},{"title":"Chucky","genre":"Horror"}]
const titles = ["Chucky","La La Land","Avengers"]

const titlesByOrder = new Map(titles.map((t, i) => [t, i]))

const result = _.sortBy(movies, o => titlesByOrder.get(o.title))

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

Если массив titles содержит заголовки для всех элементов в movies, а заголовки элементов являются уникальными, вы можете преобразовать массив movies в объект, используя _.keyBy(), а затем получить массив с правильным порядком, используя _.at():

const movies = [{"title":"La La Land","genre":"Musical"},{"title":"Avengers","genre":"Action"},{"title":"Chucky","genre":"Horror"}]
const titles = ["Chucky","La La Land","Avengers"]

const result = _.at(
  _.keyBy(movies, 'title'),
  titles
)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
...