在 node.js v11.0.0 中进行更改后,使用 array.sort(a, b) 的正确方法是什么^
What is the correct way to use array.sort(a, b) following changes made in node.js v11.0.0^
好的,所以我们有一些代码在节点 10 上运行良好并且通过了测试,现在在升级到节点 11 之后代码现在无法通过单元测试。代码映射到更改属性的对象数组,然后根据字符串名称值进行排序,即 array.sort(a, b) => a.toLowerCase() > b.toLowerCase().
它现在可以正确映射,但是排序不起作用,并且 returns 映射的数组只是没有排序,当我尝试将这两个函数拆分成单独的映射然后对排序进行排序时 returns未定义。
已经研究并试图找到一些示例以查看需要更改的内容,但除了建议在 v8 中将排序算法更改为 timsort 之外,没有发现太多。
简单代码
export default places => places
.map(place => ({
value: place.properties.code, label: place.properties.name
}))
.sort((placeA, placeB) => placeA.label.toLowerCase() >
placeB.label.toLowerCase())
测试数组:
type: 'Place',
properties: {
code: 'CA076757',
name: 'Brockway'
}
}, {
type: 'Place',
properties: {
code: 'MN486464',
name: 'Ogdenville'
}
}, {
type: 'Place',
properties: {
code: 'S4889785',
name: 'North Haverbrook'
}
}]
预期结果
{value: 'CA076757', label: 'Brockway'},
{value: 'S4889785', label: 'North Haverbrook'},
{value: 'MN486464', label: 'Ogdenville'}
]
实际结果
{value: 'CA076757', label: 'Brockway'},
{value: 'MN486464', label: 'Ogdenville'}.
{value: 'S4889785', label: 'North Haverbrook'}
]
您可以使用 localeCompare
:
export default places => places
.map(place => ({
value: place.properties.code, label: place.properties.name
}))
.sort((placeA, placeB) => placeA.label.toLowerCase().localeCompare(placeB.label.toLowerCase()));
输出:
[ { value: 'CA076757', label: 'Brockway' },
{ value: 'S4889785', label: 'North Haverbrook' },
{ value: 'MN486464', label: 'Ogdenville' } ]
we had some code that was working fine and passing tests fine on node 10, now following upgrading to node 11 the code now fails unit tests
坦率地说,这意味着您的测试没有提供足够的覆盖率;-)
在 JavaScript 中,Array.sort
的比较函数 cmp(a, b)
应该 return:
- 如果
a
小于 b
,则该值小于零
- 零,如果
a
等于 b
- 如果
a
大于 b
,则值大于零
如果您使用 return 为布尔值的比较器函数,则 false
将静默映射到 0
,而 true
将静默映射到 1
.无法发出 a < b
案例的信号。如果您的测试用例得到(或曾经得到)正确排序,那么它们就没有涵盖该案例。
无论您使用的是哪个 Node 版本或浏览器,适合您示例的比较器函数是:
(placeA, placeB) => {
let a = placeA.label.toLowerCase();
let b = placeB.label.toLowerCase();
if (a < b) return -1;
if (a > b) return 1;
return 0;
}
根据我的回答Sort array of objects by string property value, a sufficient way to sort strings when string locales都不重要,就是下面的做法:
const sortBy = fn => (a, b) => {
const fa = fn(a)
const fb = fn(b)
return -(fa < fb) || +(fa > fb)
}
const sortByLabelCaseInsensitive = sortBy(
place => place.label.toLowerCase()
)
const fn = places => places.map(place => ({
value: place.properties.code,
label: place.properties.name
})).sort(sortByLabelCaseInsensitive)
const array = [{
type: 'Place',
properties: {
code: 'CA076757',
name: 'Brockway'
}
}, {
type: 'Place',
properties: {
code: 'MN486464',
name: 'Ogdenville'
}
}, {
type: 'Place',
properties: {
code: 'S4889785',
name: 'North Haverbrook'
}
}]
console.log(fn(array))
试试这个
.sort((placeA, placeB) => {
if(placeA.label.toLowerCase() < placeB.label.toLowerCase()) return -1
if(placeA.label.toLowerCase() > placeB.label.toLowerCase()) return 1
return 0;
});
您需要将每个元素与下一个元素进行比较,return它是否相等、大于或小于
好的,所以我们有一些代码在节点 10 上运行良好并且通过了测试,现在在升级到节点 11 之后代码现在无法通过单元测试。代码映射到更改属性的对象数组,然后根据字符串名称值进行排序,即 array.sort(a, b) => a.toLowerCase() > b.toLowerCase().
它现在可以正确映射,但是排序不起作用,并且 returns 映射的数组只是没有排序,当我尝试将这两个函数拆分成单独的映射然后对排序进行排序时 returns未定义。
已经研究并试图找到一些示例以查看需要更改的内容,但除了建议在 v8 中将排序算法更改为 timsort 之外,没有发现太多。
简单代码
export default places => places
.map(place => ({
value: place.properties.code, label: place.properties.name
}))
.sort((placeA, placeB) => placeA.label.toLowerCase() >
placeB.label.toLowerCase())
测试数组:
type: 'Place',
properties: {
code: 'CA076757',
name: 'Brockway'
}
}, {
type: 'Place',
properties: {
code: 'MN486464',
name: 'Ogdenville'
}
}, {
type: 'Place',
properties: {
code: 'S4889785',
name: 'North Haverbrook'
}
}]
预期结果
{value: 'CA076757', label: 'Brockway'},
{value: 'S4889785', label: 'North Haverbrook'},
{value: 'MN486464', label: 'Ogdenville'}
]
实际结果
{value: 'CA076757', label: 'Brockway'},
{value: 'MN486464', label: 'Ogdenville'}.
{value: 'S4889785', label: 'North Haverbrook'}
]
您可以使用 localeCompare
:
export default places => places
.map(place => ({
value: place.properties.code, label: place.properties.name
}))
.sort((placeA, placeB) => placeA.label.toLowerCase().localeCompare(placeB.label.toLowerCase()));
输出:
[ { value: 'CA076757', label: 'Brockway' },
{ value: 'S4889785', label: 'North Haverbrook' },
{ value: 'MN486464', label: 'Ogdenville' } ]
we had some code that was working fine and passing tests fine on node 10, now following upgrading to node 11 the code now fails unit tests
坦率地说,这意味着您的测试没有提供足够的覆盖率;-)
在 JavaScript 中,Array.sort
的比较函数 cmp(a, b)
应该 return:
- 如果
a
小于b
,则该值小于零
- 零,如果
a
等于b
- 如果
a
大于b
,则值大于零
如果您使用 return 为布尔值的比较器函数,则 false
将静默映射到 0
,而 true
将静默映射到 1
.无法发出 a < b
案例的信号。如果您的测试用例得到(或曾经得到)正确排序,那么它们就没有涵盖该案例。
无论您使用的是哪个 Node 版本或浏览器,适合您示例的比较器函数是:
(placeA, placeB) => {
let a = placeA.label.toLowerCase();
let b = placeB.label.toLowerCase();
if (a < b) return -1;
if (a > b) return 1;
return 0;
}
根据我的回答Sort array of objects by string property value, a sufficient way to sort strings when string locales都不重要,就是下面的做法:
const sortBy = fn => (a, b) => {
const fa = fn(a)
const fb = fn(b)
return -(fa < fb) || +(fa > fb)
}
const sortByLabelCaseInsensitive = sortBy(
place => place.label.toLowerCase()
)
const fn = places => places.map(place => ({
value: place.properties.code,
label: place.properties.name
})).sort(sortByLabelCaseInsensitive)
const array = [{
type: 'Place',
properties: {
code: 'CA076757',
name: 'Brockway'
}
}, {
type: 'Place',
properties: {
code: 'MN486464',
name: 'Ogdenville'
}
}, {
type: 'Place',
properties: {
code: 'S4889785',
name: 'North Haverbrook'
}
}]
console.log(fn(array))
试试这个
.sort((placeA, placeB) => {
if(placeA.label.toLowerCase() < placeB.label.toLowerCase()) return -1
if(placeA.label.toLowerCase() > placeB.label.toLowerCase()) return 1
return 0;
});
您需要将每个元素与下一个元素进行比较,return它是否相等、大于或小于