在 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它是否相等、大于或小于