如何使用 lodash 的 _sortBy() 按自定义要求按字母顺序排序此列表?
How to use lodash's _sortBy() to alphabetically sort this list with a custom requirement?
我有以下对象数组:
const myList = [
{ id: 1, title: '[A] Animal Bite - F - Not Pregnant' },
{ id: 2, title: '[P] Sinus Pain - M' },
{ id: 3, title: '[A] Animal Bite - F - Pregnant' },
{ id: 4, title: 'Check up male' },
{ id: 5, title: '[A] Animal Bite - M' },
{ id: 6, title: 'Duration' },
{ id: 7, title: '[P] Skin Injury - F - Not Pregnant' },
{ id: 8, title: '[P] Skin Injury - M' },
{ id: 9, title: 'Emergency Screening' }
]
完成后:
_.sortBy(myList, 'title');
我得到:
Check up male
Duration
Emergency Screening
[A] Animal Bite - F - Not Pregnant
[A] Animal Bite - F - Pregnant
[A] Animal Bite - M
[P] Sinus Pain - M
[P] Skin Injury - F - Not Pregnant
[P] Skin Injury - M
看起来不错,只是我希望没有 [A] 或 [P] 的项目位于底部而不是顶部。所以像这样:
[A] Animal Bite - F - Not Pregnant
[A] Animal Bite - F - Pregnant
[A] Animal Bite - M
[P] Sinus Pain - M
[P] Skin Injury - F - Not Pregnant
[P] Skin Injury - M
Check up male
Duration
Emergency Screening
如何实现?
这是使用函数 Array.prototype.sort()
的替代方法
假设字符串中最多有一个[
。
const myList = [ { id: 1, title: '[A] Animal Bite - F - Not Pregnant' }, { id: 2, title: '[P] Sinus Pain - M' }, { id: 3, title: '[A] Animal Bite - F - Pregnant' }, { id: 4, title: 'Check up male' }, { id: 5, title: '[A] Animal Bite - M' }, { id: 6, title: 'Duration' }, { id: 7, title: '[P] Skin Injury - F - Not Pregnant' }, { id: 8, title: '[P] Skin Injury - M' }, { id: 9, title: 'Emergency Screening' }];
myList.sort((a, b) => {
if (a.title.startsWith("[") && b.title.startsWith("[")) {
return a.title.substring(1).localeCompare(b.title.substring(1));
}
return a.title.localeCompare(b.title);
});
console.log(myList);
.as-console-wrapper { max-height: 100% !important; top: 0; }
在排序函数中使用 localeCompare
和 numeric: false
选项:
const list = [ { id: 1, title: '[A] Animal Bite - F - Not Pregnant' }, { id: 2, title: '[P] Sinus Pain - M' }, { id: 3, title: '[A] Animal Bite - F - Pregnant' }, { id: 4, title: 'Check up male' }, { id: 5, title: '[A] Animal Bite - M' }, { id: 6, title: 'Duration' }, { id: 7, title: '[P] Skin Injury - F - Not Pregnant' }, { id: 8, title: '[P] Skin Injury - M' }, { id: 9, title: 'Emergency Screening' } ]
const r = list.sort((a,b) => a.title.localeCompare(b.title, 0, {numeric: false}))
console.log(r)
您也可以获得相同结果的另一种方法是通过 {caseFirst: lower'}
选项参数,如 @xehpuk
asnwer 所述(并解释):
const list = [ { id: 1, title: '[A] Animal Bite - F - Not Pregnant' }, { id: 2, title: '[P] Sinus Pain - M' }, { id: 3, title: '[A] Animal Bite - F - Pregnant' }, { id: 4, title: 'Check up male' }, { id: 5, title: '[A] Animal Bite - M' }, { id: 6, title: 'Duration' }, { id: 7, title: '[P] Skin Injury - F - Not Pregnant' }, { id: 8, title: '[P] Skin Injury - M' }, { id: 9, title: 'Emergency Screening' } ]
const r = list.sort((a,b) => a.title.localeCompare(b.title, 0, {caseFirst: 'lower'}))
console.log(r)
如果 ES6 是一个选项,您也不需要 lodash。
lodash 的 sortBy
可能会采用比较器列表。所以你可以声明 "words don't start from square bracket go later" 并在 "group" 中按标题排序
_.sortBy(myList, [
item => !item.title.startsWith("["),
'title'
]);
并且使用 orderBy
您甚至可以以更具可读性(和灵活)的方式指定顺序:
_.orderBy(myList, [
item => item.title.startsWith("["),
'title'
], ['desc', 'asc']);
[UPD] @Ele 提到的 startsWith
看起来更好
如果你真的想用lodash,可以对比一下lower-case中的标题:
_.sortBy(myList, item => item.title.toLowerCase());
这是有效的,因为 lower-case 个字符的代码单元 (97 - 122) 大于 [
个字符 (91) 的代码单元。这也有利于比较标题 case-insensitively.
您可以通过检查字符串将括号部分移到顶部,然后取本地比较结果。
const
startsWithBrackets = s => /^\[.+\]/.test(s),
myList = [{ id: 1, title: '[A] Animal Bite - F - Not Pregnant' }, { id: 2, title: '[P] Sinus Pain - M' }, { id: 3, title: '[A] Animal Bite - F - Pregnant' }, { id: 4, title: 'Check up male' }, { id: 5, title: '[A] Animal Bite - M' }, { id: 6, title: 'Duration' }, { id: 7, title: '[P] Skin Injury - F - Not Pregnant' }, { id: 8, title: '[P] Skin Injury - M' }, { id: 9, title: 'Emergency Screening' }];
myList.sort(({ title: a }, { title: b }) =>
startsWithBrackets(b) - startsWithBrackets(a) || a.localeCompare(b));
console.log(myList);
.as-console-wrapper { max-height: 100% !important; top: 0; }
我有以下对象数组:
const myList = [
{ id: 1, title: '[A] Animal Bite - F - Not Pregnant' },
{ id: 2, title: '[P] Sinus Pain - M' },
{ id: 3, title: '[A] Animal Bite - F - Pregnant' },
{ id: 4, title: 'Check up male' },
{ id: 5, title: '[A] Animal Bite - M' },
{ id: 6, title: 'Duration' },
{ id: 7, title: '[P] Skin Injury - F - Not Pregnant' },
{ id: 8, title: '[P] Skin Injury - M' },
{ id: 9, title: 'Emergency Screening' }
]
完成后:
_.sortBy(myList, 'title');
我得到:
Check up male
Duration
Emergency Screening
[A] Animal Bite - F - Not Pregnant
[A] Animal Bite - F - Pregnant
[A] Animal Bite - M
[P] Sinus Pain - M
[P] Skin Injury - F - Not Pregnant
[P] Skin Injury - M
看起来不错,只是我希望没有 [A] 或 [P] 的项目位于底部而不是顶部。所以像这样:
[A] Animal Bite - F - Not Pregnant
[A] Animal Bite - F - Pregnant
[A] Animal Bite - M
[P] Sinus Pain - M
[P] Skin Injury - F - Not Pregnant
[P] Skin Injury - M
Check up male
Duration
Emergency Screening
如何实现?
这是使用函数 Array.prototype.sort()
假设字符串中最多有一个[
。
const myList = [ { id: 1, title: '[A] Animal Bite - F - Not Pregnant' }, { id: 2, title: '[P] Sinus Pain - M' }, { id: 3, title: '[A] Animal Bite - F - Pregnant' }, { id: 4, title: 'Check up male' }, { id: 5, title: '[A] Animal Bite - M' }, { id: 6, title: 'Duration' }, { id: 7, title: '[P] Skin Injury - F - Not Pregnant' }, { id: 8, title: '[P] Skin Injury - M' }, { id: 9, title: 'Emergency Screening' }];
myList.sort((a, b) => {
if (a.title.startsWith("[") && b.title.startsWith("[")) {
return a.title.substring(1).localeCompare(b.title.substring(1));
}
return a.title.localeCompare(b.title);
});
console.log(myList);
.as-console-wrapper { max-height: 100% !important; top: 0; }
在排序函数中使用 localeCompare
和 numeric: false
选项:
const list = [ { id: 1, title: '[A] Animal Bite - F - Not Pregnant' }, { id: 2, title: '[P] Sinus Pain - M' }, { id: 3, title: '[A] Animal Bite - F - Pregnant' }, { id: 4, title: 'Check up male' }, { id: 5, title: '[A] Animal Bite - M' }, { id: 6, title: 'Duration' }, { id: 7, title: '[P] Skin Injury - F - Not Pregnant' }, { id: 8, title: '[P] Skin Injury - M' }, { id: 9, title: 'Emergency Screening' } ]
const r = list.sort((a,b) => a.title.localeCompare(b.title, 0, {numeric: false}))
console.log(r)
您也可以获得相同结果的另一种方法是通过 {caseFirst: lower'}
选项参数,如 @xehpuk
asnwer 所述(并解释):
const list = [ { id: 1, title: '[A] Animal Bite - F - Not Pregnant' }, { id: 2, title: '[P] Sinus Pain - M' }, { id: 3, title: '[A] Animal Bite - F - Pregnant' }, { id: 4, title: 'Check up male' }, { id: 5, title: '[A] Animal Bite - M' }, { id: 6, title: 'Duration' }, { id: 7, title: '[P] Skin Injury - F - Not Pregnant' }, { id: 8, title: '[P] Skin Injury - M' }, { id: 9, title: 'Emergency Screening' } ]
const r = list.sort((a,b) => a.title.localeCompare(b.title, 0, {caseFirst: 'lower'}))
console.log(r)
如果 ES6 是一个选项,您也不需要 lodash。
lodash 的 sortBy
可能会采用比较器列表。所以你可以声明 "words don't start from square bracket go later" 并在 "group" 中按标题排序
_.sortBy(myList, [
item => !item.title.startsWith("["),
'title'
]);
并且使用 orderBy
您甚至可以以更具可读性(和灵活)的方式指定顺序:
_.orderBy(myList, [
item => item.title.startsWith("["),
'title'
], ['desc', 'asc']);
[UPD] @Ele 提到的 startsWith
看起来更好
如果你真的想用lodash,可以对比一下lower-case中的标题:
_.sortBy(myList, item => item.title.toLowerCase());
这是有效的,因为 lower-case 个字符的代码单元 (97 - 122) 大于 [
个字符 (91) 的代码单元。这也有利于比较标题 case-insensitively.
您可以通过检查字符串将括号部分移到顶部,然后取本地比较结果。
const
startsWithBrackets = s => /^\[.+\]/.test(s),
myList = [{ id: 1, title: '[A] Animal Bite - F - Not Pregnant' }, { id: 2, title: '[P] Sinus Pain - M' }, { id: 3, title: '[A] Animal Bite - F - Pregnant' }, { id: 4, title: 'Check up male' }, { id: 5, title: '[A] Animal Bite - M' }, { id: 6, title: 'Duration' }, { id: 7, title: '[P] Skin Injury - F - Not Pregnant' }, { id: 8, title: '[P] Skin Injury - M' }, { id: 9, title: 'Emergency Screening' }];
myList.sort(({ title: a }, { title: b }) =>
startsWithBrackets(b) - startsWithBrackets(a) || a.localeCompare(b));
console.log(myList);
.as-console-wrapper { max-height: 100% !important; top: 0; }