【问题标题】:How can I sort students by first and last name while ignoring apostrophe in their name?如何在忽略他们名字中的撇号的同时按名字和姓氏对学生进行排序?
【发布时间】:2021-06-14 18:17:53
【问题描述】:

我试图在忽略撇号的同时对名称进行排序。现在我正在使用 Javascript 并使用 mongodb 查询 mongo 数据库。在查询中,我通过lastNamefirstName 对学生使用$sort。但是,当返回姓名时,姓名中带有' 的学生会排在没有姓名的学生之前。例如:

ex: (random, unsorted) 
D'Marcus O'Connell
Damian O'Connell
Damian O'Claire
Dylan Oliver

在这里,D'Marcus O'Connell 将在 Damian O'Connell 之前,根据我的 $sort。但是,客户正在使用来自其遗留系统的单独成绩簿服务来导入名册,并且在他们的列表中,他们将忽略',而Damian O'Connell 将出现在D'Marcus O'Connell 之前,因为am 之前字母表。 (我想也忽略具有不同字符值的大写字母?)

以下是我必须处理的来自查询的数据。现在我有过多的数组以防万一它可能有用。最初我想我会尝试对姓氏进行排序循环,如果姓氏相等,请检查名字......但我不知道如何去除' 中间排序或预排序。 (这里,ArchieGlenn 是我用作排序测试对象的两个独立名称,这就是它们被硬编码的原因)

var sortNamesArr = [];
var studentObjTemp = {};
var lastNamesArr = [];
var firstNamesArr = [];
for (i = 0; i < response[0].gridData.length; i++) {
    var lastName = response[0].gridData[i].lastName;
    var firstName = response[0].gridData[i].firstName;
    if (firstName == "Archie") {
        firstName = "A'rchie";
    }
    if (lastName == "Glenn") {
        lastName = "G'lenn";
    }
    studentObjTemp = {lastName, firstName};
    sortNamesArr.push(studentObjTemp);
    lastNamesArr.push(response[0].gridData[i].lastName);
    firstNamesArr.push(response[0].gridData[i].firstName);
}

请,任何帮助将不胜感激。如果至少你能指出我正确的方向。我看过其他使用正则表达式去除撇号的帖子,但它们似乎对我不起作用。

编辑:这是返回一组包含学生姓名的网格数据后的 sortNamesArr 示例 -

(10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
0: {lastName: "Bowser", firstName: "Arnoldo"}
1: {lastName: "Coffey", firstName: "Abel"}
2: {lastName: "Dahl", firstName: "Alexis"}
3: {lastName: "Doyle", firstName: "A'rchie"}
4: {lastName: "Esquivel", firstName: "Bernadine"}
5: {lastName: "Fuller", firstName: "Ariel"}
6: {lastName: "G'lenn", firstName: "Anastasia"}
7: {lastName: "Nava", firstName: "Adrianne"}
8: {lastName: "Perry", firstName: "Alberta"}
9: {lastName: "Vera", firstName: "Anthony"}

【问题讨论】:

  • 您是想去掉's 以便存储的数据发生变化,还是只是为了排序而忽略它们?
  • @B-Schmidt 仅用于排序。之后他们必须保留名称中的 '

标签: javascript regex mongodb sorting


【解决方案1】:

您可以使用localeCompareignorePunctuation 选项来排序忽略标点符号。

const names = [{lastName: "Bowser", firstName: "Arnoldo"}, {lastName: "Coffey", firstName: "Abel"}, {lastName: "Dahl", firstName: "Alexis"}, {lastName: "Doyle", firstName: "A'rchie"}, {lastName: "Esquivel", firstName: "Bernadine"}, {lastName: "Fuller", firstName: "Ariel"},{lastName: "G'lenn", firstName: "Anastasia"}, {lastName: "Nava", firstName: "Adrianne"}, {lastName: "Perry", firstName: "Alberta"}, {lastName: "Vera", firstName: "Anthony"}];
names.sort((a, b) => a.firstName.localeCompare(b.firstName, undefined, {ignorePunctuation: true }) || a.lastName.localeCompare(b.lastName, undefined, { ignorePunctuation: true }));
console.log(names);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 这种事情是否也适用于我当前的 lastName 和 firstName 是分隔值的示例?我总是可以将它们连接成一个字符串然后再次拆分,但我认为这会与字母顺序混淆,除非我弄错了。编辑:我应该澄清一下——姓氏是主要的,然后名字是次要的。所以首先它根据lastName 排序,然后如果lastName 相等,它就根据firstName 排序。虽然我喜欢这个 localeCompare 的想法,但我会尝试一下!
  • 是的,它将按多个字段排序。可以分享一些数据吗?
  • 是的,我将添加一个示例,说明上面在编辑我的帖子时将返回的内容(在 cmets 中无法真正格式化)
  • 我收到的关于这个请求的具体问题是关于对 O'Neal 和 Oliver 的姓氏进行排序。在他们的遗留成绩册中,它将显示为 Oliver,Brady;然后是奥尼尔斯蒂芬。与奥尼尔和奥利弗相反。
  • @AliveSquare 我已经更新了答案。它将首先按firstNamelastName 排序。
【解决方案2】:

你可以在 javascript 中实现你的排序回调,所以它会是这样的

const names = [
  {firstName: "D'Marcus", lastName: "O'Connell"},
  {firstName: "Damian", lastName: "O'Connell"},
  {firstName: "Damian", lastName: "O'Claire"}
]

names.sort((a,b) => {
    var auxA = a.firstName.split("'")
    var auxB = b.firstName.split("'");
    if(auxA.join('').toUpperCase() > auxB.join('').toUpperCase()) return 1;
    else if(auxA.join('').toUpperCase() < auxB.join('').toUpperCase())  return -1;
    else {
      auxA = a.lastName.split("'")
      auxB = b.lastName.split("'");
      if(auxA.join('').toUpperCase() > auxB.join('').toUpperCase()) return 1;
      else if (auxA.join('').toUpperCase() < auxB.join('').toUpperCase()) return -1;
    }
  }
)
console.log(names)
[
  { firstName: 'Damian', lastName: "O'Claire" },
  { firstName: 'Damian', lastName: "O'Connell" },
  { firstName: "D'Marcus", lastName: "O'Connell" }
]

我们将firstName拆分为有一个'的地方并保存在一些辅助变量中,然后我们将这两个变量与join()toUpperCase()进行比较,检查哪个大于另一个并返回该值,如果它们相等,我对lastName 做同样的事情。这将返回您的数组排序。注意:“'”仍然会出现在response[0].gridData 中。

【讨论】:

  • 我会将其实现为对象数组吗? sortNamesArr = [ {lastName1, firstName1}, {lastName2, firstName2} 等...]。 => sortNamesArr.sort...并利用您的上述逻辑?
  • 是的,实现一个对象数组。在您的示例中,您有一个包含两个属性firstNamelastName 的对象数组,因此我创建了一个考虑到这一点的排序函数。
  • 正如您所说,您的问题是首先对lastName 进行排序,您只需要在我的示例中更改顺序,在我的示例中它是比较firstName 的排序。
  • 成功了!谢谢你的意见。我有点困惑 auxA 连接如何仍在工作以组合回字符串,但现在我明白了。感谢您的帮助
猜你喜欢
  • 2010-10-26
  • 2020-11-03
  • 2019-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多