首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么compareFunction必须考虑负面因素?

为什么compareFunction必须考虑负面因素?
EN

Stack Overflow用户
提问于 2017-08-19 15:46:53
回答 4查看 245关注 0票数 1

Array.prototype.sort()

compareFunction(a, b)中,只有当我们需要交换a和b的位置时,我们才返回一个正值。

如果省略了compareFunction中的负Array.prototype.sort(),那么为什么开发人员应该编写返回负值的if-statement呢?

代码语言:javascript
运行
复制
var list = [4, 5, 3, 5, 6, 9, 1, 4, 2];
list = list.sort(function(a, b) {
  if (a > b) {
    return 1;
  }
});
console.log(list); // correct result

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-08-19 16:50:21

这里的主要问题是,您已经发明了自己对比较函数的定义,并将您的问题建立在这样的基础之上:

在compareFunction(a,b)中,只有当我们需要交换a和b的位置时,我们才返回一个正值。

这是错误的。“当我们需要交换a和b的位置时”是实现细节,您正在将实现与接口混淆。

compareFunction不负责指示何时交换两个元素。它负责准确地传达两个要素之间的关系。排序算法对该信息的处理取决于实现者。如果您只在某些时候返回正确的值,那么您就不能一直期望得到正确的结果。

例如,排序实现者可以实现这样的排序(基于https://www.nczonline.net/blog/2012/09/17/computer-science-in-javascript-insertion-sort/上的示例)。如果我使用有效的比较函数运行它,它将产生正确的结果:

代码语言:javascript
运行
复制
function insertionSort(items, compare) {

  var len = items.length, // number of items in the array
    value, // the value currently being compared
    i, // index into unsorted section
    j; // index into sorted section

  for (i = 0; i < len; i++) {

    // store the current value because it may shift later
    value = items[i];

    for (j = i - 1; j > -1 && compare(value, items[j]) < 0; j--) {
      items[j + 1] = items[j];
    }

    items[j + 1] = value;
  }

  return items;
}

console.log(insertionSort([4,2,6,1,7,2], (l, r) => l - r));

如果我用您的比较函数运行它,它什么也不做:

代码语言:javascript
运行
复制
function insertionSort(items, compare) {

  var len = items.length, // number of items in the array
    value, // the value currently being compared
    i, // index into unsorted section
    j; // index into sorted section

  for (i = 0; i < len; i++) {

    // store the current value because it may shift later
    value = items[i];

    for (j = i - 1; j > -1 && compare(value, items[j]) < 0; j--) {
      items[j + 1] = items[j];
    }

    items[j + 1] = value;
  }

  return items;
}

console.log(insertionSort([4,2,6,1,7,2], function(a, b) {
    if (a > b) {
        return 1;
    }
}));

票数 3
EN

Stack Overflow用户

发布于 2017-08-19 17:00:07

这在你的情况下是可行的,因为你没有测试所有的可能性。但是,如果您查看实施内部,您会发现引擎没有在短数组(即。长度( <= 10)比长数组上长。实际上,insertion sort用于短数组,而QuickSort则用于长数组。

由于您的实现必须定义哪个数字更高、更低或等于另一个数字,所以在较长的数组中,它将失败,因为您忘记了实现“下面”大小写(并且隐含了相等的大小写,因为您的函数将在b >= a 这将被解释 as 0时返回它的值),因此QuickSort将无法正确排序数组,因为它无法知道某个数字小于另一个数字的时间,而插入排序由于它的算法而工作,如果我正确理解它的话,该算法依赖于“大于”的比较。

见下面的例子:

代码语言:javascript
运行
复制
var shortList = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0],
    list = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0];
    
console.log('Works : ', shortList.sort(function(a, b) {
  if (a > b) {
    return 1;
  }
})); // You're being lucky on this one. Insertion sort.

console.log('Doesnt work : ', list.sort(function(a, b) {
  if (a > b) {
    return 1;
  }
})); // QuickSort

console.log('Works : ', list.sort(function(a, b) {
  if (a > b) {
    return 1;
  } else if (a < b) {
    return -1;
  }
  
  return a - b; // Can be reduced to 'return a - b';
})); // QuickSort

票数 1
EN

Stack Overflow用户

发布于 2017-08-19 15:56:21

如果您不遵循规范,那么您很可能会看到跨引擎的不一致,因为浏览器(例如)不知道如何处理它。Chrome、Firefox和Node.js似乎很好地按照您的预期对数组进行了排序,但是Safari并没有对数组进行排序,例如:

代码语言:javascript
运行
复制
[4, 5, 3, 5, 6, 9, 1, 4, 2]

我希望所有这些浏览器在没有实现规范时都会失败,比如"Error: RTM“。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45773457

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档