ES6 groupBy, раздел, сортировка списка объектов - PullRequest
0 голосов
/ 24 августа 2018

Я пытаюсь найти элегантный способ в ES6 сортировать массив объектов на основе указанных значений.Вот сценарий:

const list = [
{
"name": "john",
"lastName": "smith"
}, {
"name": "tony",
"lastName": "smith"
}, {
"name": "tony",
"lastName": "grey"
}, {
"name": "mary",
"lastName": "smith"
}, {
"name": "john",
"lastName": "x"
}, {
"name": "tom",
"lastName": "y"
}
, {
"name": "mary",
"lastName": "x"
}
]

let orderList = [{"name":["john","mary"]}, {"lastName":["x"]}];

Итак, в основном сортируем результат по именам (Джон, Мэри), а затем сортируем результат по lastName (x), но сортировка имен по-прежнему имеет приоритет.Результат должен выглядеть следующим образом:

[
  {
   "name": "john",
   "lastName": "x"
  }, {
   "name": "john",
   "lastName": "smith"
  }, {
    "name": "mary",
   "lastName": "x"
  }, {
   "name": "mary",
   "lastName": "smith"
  }, {
   "name": "tony",
   "lastName": "smith"
   }, {
    "name": "tony",
    "lastName": "grey"
   }, {
    "name": "tom",
    "lastName": "y"
   }
 ]

Я уже пытался что-то сделать с группой по, но это ручной процесс для каждого имени и фамилии.

_.groupBy(list , {"name": "john"});

Я также пытался поэкспериментировать с уменьшением массива, но не могу найти хорошее динамическое решение.

const sortArr = ['john', 'mary'];
const sortedList= list.reduce((result, element) => {
   let index = sortArr.findIndex(x => x === element.name);
   result[index !== -1
      ? index
      : result.length - 1].push(element); 
     return result;
       },[  [], [], [] ]);

Любая помощь приветствуется.Спасибо

1 Ответ

0 голосов
/ 24 августа 2018

Вы можете использовать Array#sort и использовать итерационный подход для сортировки сначала по name, а затем по lastName.

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

Для получения дельты выполняется поиск Array#indexOf, а если -1, значение дляэлемент not found, заменяется на Infinity, поскольку этот элемент должен быть отсортирован до конца массива.Элементы с найденным индексом сортируются в соответствии с индексом.

Для более быстрой сортировки объекты с одной парой ключ / значение преобразуются в массив с ключом и значением.

var list = [{ name: "john", lastName: "smith" }, { name: "tony", lastName: "smith" }, { name: "tony", lastName: "grey" }, { name: "mary", lastName: "smith" }, { name: "john", lastName: "x" }, { name: "tom", lastName: "y" }, { name: "mary", lastName: "x" }],
    orderList = [{ name: ["john", "mary"] }, { lastName: ["x"] }],
    order = orderList.map(o => (k => [k, o[k]])(Object.keys(o)[0]));

list.sort((a, b) => {
    var d;
    order.some(([k, v]) =>
        d = (v.indexOf(a[k]) + 1 || Infinity) - (v.indexOf(b[k]) + 1 || Infinity)
    );
    return d;
});

console.log(list);
.as-console-wrapper { max-height: 100% !important; top: 0; }
...