Javascript localecompare - 首先排序的大写字母

时间:2018-03-30 13:17:54

标签: javascript arrays sorting

我正在尝试对包含lastNamefirstName属性的对象数组进行排序。如果对象具有相同的lastName,我希望按asc顺序按firstName排序,然后按asc顺序按lastName排序。

下面是我需要的排序顺序(标准字母排序顺序)。

[symbols, numbers, 'A-Z', 'a-z']

我使用了localeCompare,但它按以下排序顺序对字符串进行排序。

[symbols, numbers, 'a-z', 'A-Z'] 

小写字母位于大写字母

之前

例如:如果数组包含以下元素

let guests = [
{
lastName: "guest",
firstName: "abc"
},
{
lastName: "Guest",
firstName: "test"
},
{
lastName: "guest",
firstName: "Abc"
},
{
lastName: "guest",
firstName: "123"
}
];

我希望对象的排序方式如下:

[
    {
    lastName: "Guest",
    firstName: "test"
    },
    {
    lastName: "guest",
    firstName: "123"
    },
    {
    lastName: "guest",
    firstName: "Abc",
    },
    {
    lastName: "guest",
    firstName: "abc"
    }
]

但我得到的结果是

[
    {
    lastName: "guest",
    firstName: "123"
    },
    {
    lastName: "guest",
    firstName: "abc"
    },
    {
    lastName: "guest",
    firstName: "Abc",
    },
    {
    lastName: "Guest",
    firstName: "test"
    }
]

以下是我尝试的代码。



let guests = [
              {
                lastName: "guest",
                firstName: "abc"
              },
              {
                lastName: "Guest",
                firstName: "test"
              },
              {
                lastName: "guest",
                firstName: "Abc"
              },
              {
                lastName: "guest",
                firstName: "123"
              }
            ];

            guests.sort((a, b) => {
              if (_.get(a, 'lastName') === _.get(b, 'lastName')) {
                return _.get(a, 'firstName', '').localeCompare(_.get(b, 'firstName', ''));
              } else {
                return _.get(a, 'lastName', '').localeCompare(_.get(b, 'lastName', ''));
              }
            });
            
             console.log(guests);

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.min.js"></script>
&#13;
&#13;
&#13;

我从localeCompare的文档中了解到它接受options对象,我们可以在其中指定caseFirst属性,指定大写和小写字母的排序顺序。

下面使用options参数的代码片段产生了我期望的输出,但问题是,它尚未在所有浏览器中受支持。

&#13;
&#13;
					let guests = [
        {
        lastName: "guest",
        firstName: "abc"
        },
        {
        lastName: "Guest",
        firstName: "test"
        },
        {
        lastName: "guest",
        firstName: "Abc"
        },
        {
        lastName: "guest",
        firstName: "123"
        }
        ];
        
    guests.sort((a, b) => {
                          if (_.get(a, 'lastName') === _.get(b, 'lastName')) {
                            return _.get(a, 'firstName', '').localeCompare(_.get(b, 'firstName', ''), undefined, {caseFirst: 'upper'});
                          } else {
                            return _.get(a, 'lastName', '').localeCompare(_.get(b, 'lastName', ''), undefined, {caseFirst: 'upper'});
                          }
                        });
                        
    console.log(guests);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.min.js"></script>
&#13;
&#13;
&#13;

有没有办法在不使用options参数的情况下完成结果。是否有一个自定义排序方法,我可以传递给JS array.sort(),以实现我的目标。请帮忙。

1 个答案:

答案 0 :(得分:1)

由于aA在不区分大小写的比较中被视为相等,因此未指定其排序顺序。您需要检查它们是否匹配,如果不是,则应用自定义排序。

guests.sort((a,b) => {
    return _.get(a, 'lastName', '').localeCompare(_.get(b, 'lastName', ''))
    || _.get(a, 'firstName', '').localeCompare(_.get(b, 'firstName', ''))
    || (_.get(a, 'lastName', '') > _.get(b, 'lastName', '') ? 1 : -1);
});

这将按姓氏排序,然后按名字排序,然后(如果两者相等)它将在小写之前排序大写(因为这是二进制字符串比较的工作方式)。