ES6的 groupBy、partition 和 sort 对象列表

4

我正在尝试在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"]}];

所以,基本上按照姓名(John, Mary)对结果进行排序,然后按照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"
   }
 ]

我已经尝试过使用group by来做一些事情,但对于每个名字和姓氏都需要手动处理。

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

我还尝试过使用数组reduce进行实验,但似乎找不到一个好的动态解决方案。

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;
       },[  [], [], [] ]);

非常感谢您的帮助。谢谢。


为什么不编写自定义比较函数并使用Array.sort呢? - James
可能是如何在多个列上对数组进行排序?的重复问题。 - Andreas
你到底想做什么?按名字的首字母排序,然后把姓氏为“x”的人放在最前面? - TheMagicalCake
“order” 数组我猜类似于 SQL 的 ORDER BY 子句,所以按照第一项 - 名称 - 采用特殊规则排序,然后按照第二项 - 姓氏 - 排序。 - James
1个回答

3
您可以使用Array#sort来分别按照namelastName的顺序进行迭代排序。
此方案通过检查属性是否在数组中并将这些值按照索引差异排序到顶部来实现。重复此步骤,直到差异为零或排序数组已结束。
为了获得差异,进行了一个Array#indexOf搜索,如果-1表示未找到该项,则用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; }


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接