2021-01-22

[转载或参考] https://blog.csdn.net/github_39319000/article/details/89554079

[转载或参考]https://blog.csdn.net/weixin_33862188/article/details/88679236

【仅供自己学习查询, 侵删】

关于 sort () 比较 遇到的坑,浅析 【附带:源码】

1、 不传值(默认)

示例: 

var arr = [1, 5, 11, 10]

arr.sort() //  [1, 10, 11, 5]

这里并没有得到我们想要的 [1, 5 ,10, 11]

原因: 

  1. 默认情况,sort 是升序
  2. sort 默认会将 元素转化成 string 类型 , 因此这儿的 Number 类型比较的其实是 String 类型。

回顾下: 字符串的比较:

abc

abde 

"c".charCodeAt() // 99
"d".charCodeAt() // 100

a-z	97-122
A-Z	65-90
0-9	45-57

字符串大小比较是 比较相同index字符的 ASII码, c (99) < d (100)

因此 abc < abd

回顾问题: "5" 和 "11", 比较第一位, "1" 为46, "5"为 50, 故 "1"<"5", 比较结束, "11"<"5",

得出: [1, 10, 11, 5]

 

2、 函数返回值 bool 类型 (坑)

var arr = [1, 10, 5, 11] //  目标值: [1, 5, 10, 11]

// 返回 bool 值
arr.sort((x,y)=> x>y ) // [1, 10, 5, 11] 未生效


// 返回 Number 值
arr.sort((x,y)=> x-y ) // [1, 5, 10, 11] 生效

原因: 当传入回调函数时候,

 返回 bool 值,不生效

返回 Bumber 值时候, 生效。 转化成的 true 和 false 并不会转化成数值,因此不生效。

原因是因为,sort ( fn ) 会调用 fn ,最后根据 数字 进行区分,

  • 当等于0时, 不移动
  • 等大于0时, 交换
  • 当小于0时,交换

 

3、总结: 

  1.  不传值,默认升序,会转化成 字符串进行比较
  2. 有fn传值,根据 return 的 Number 值进行比较,注意 retrun 布尔类型值。函数不生效。

 

    3、数据元素少的时候,采用的是插入排序, 元素多的时候,采用的是快排。

4、V8引擎源码

function ArraySort(comparefn) {
  // In-place QuickSort algorithm.
  // For short (length <= 22) arrays, insertion sort is used for efficiency.

  var custom_compare = IS_FUNCTION(comparefn);

  function Compare(x,y) {
    // Assume the comparefn, if any, is a consistent comparison function.
    // If it isn't, we are allowed arbitrary behavior by ECMA 15.4.4.11.
    if (x === y) return 0;
    if (custom_compare) {
      // Don't call directly to avoid exposing the builtin's global object.
      return comparefn.call(null, x, y);
    }
    if (%_IsSmi(x) && %_IsSmi(y)) {
      return %SmiLexicographicCompare(x, y);
    }
    x = ToString(x);
    y = ToString(y);
    if (x == y) return 0;
    else return x < y ? -1 : 1;
  };

  function InsertionSort(a, from, to) {
    for (var i = from + 1; i < to; i++) {
      var element = a[i];
      // Pre-convert the element to a string for comparison if we know
      // it will happen on each compare anyway.
      var key =
          (custom_compare || %_IsSmi(element)) ? element : ToString(element);
      // place element in a[from..i[
      // binary search
      var min = from;
      var max = i;
      // The search interval is a[min..max[
      while (min < max) {
        var mid = min + ((max - min) >> 1);
        var order = Compare(a[mid], key);
        if (order == 0) {
          min = max = mid;
          break;
        }
        if (order < 0) {
          min = mid + 1;
        } else {
          max = mid;
        }
      }
      // place element at position min==max.
      for (var j = i; j > min; j--) {
        a[j] = a[j - 1];
      }
      a[min] = element;
    }
  }

  function QuickSort(a, from, to) {
    // Insertion sort is faster for short arrays.
    if (to - from <= 22) {
      InsertionSort(a, from, to);
      return;
    }
    var pivot_index = $floor($random() * (to - from)) + from;
    var pivot = a[pivot_index];
    // Pre-convert the element to a string for comparison if we know
    // it will happen on each compare anyway.
    var pivot_key =
      (custom_compare || %_IsSmi(pivot)) ? pivot : ToString(pivot);
    // Issue 95: Keep the pivot element out of the comparisons to avoid
    // infinite recursion if comparefn(pivot, pivot) != 0.
    a[pivot_index] = a[from];
    a[from] = pivot;
    var low_end = from;   // Upper bound of the elements lower than pivot.
    var high_start = to;  // Lower bound of the elements greater than pivot.
    // From low_end to i are elements equal to pivot.
    // From i to high_start are elements that haven't been compared yet.
    for (var i = from + 1; i < high_start; ) {
      var element = a[i];
      var order = Compare(element, pivot_key);
      if (order < 0) {
        a[i] = a[low_end];
        a[low_end] = element;
        i++;
        low_end++;
      } else if (order > 0) {
        high_start--;
        a[i] = a[high_start];
        a[high_start] = element;
      } else {  // order == 0
        i++;
      }
    }
    QuickSort(a, from, low_end);
    QuickSort(a, high_start, to);
  }

  var old_length = ToUint32(this.length);
  if (old_length < 2) return this;

  %RemoveArrayHoles(this);

  var length = ToUint32(this.length);

  // Move undefined elements to the end of the array.
  for (var i = 0; i < length; ) {
    if (IS_UNDEFINED(this[i])) {
      length--;
      this[i] = this[length];
      this[length] = void 0;
    } else {
      i++;
    }
  }

  QuickSort(this, 0, length);

  // We only changed the length of the this object (in
  // RemoveArrayHoles) if it was an array.  We are not allowed to set
  // the length of the this object if it is not an array because this
  // might introduce a new length property.
  if (IS_ARRAY(this)) {
    this.length = old_length;
  }

  return this;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园建设方案旨在通过融合先进技术,如物联网、大数据、人工智能等,实现校园的智能化管理与服务。政策的推动和技术的成熟为智慧校园的发展提供了基础。该方案强调了数据的重要性,提出通过数据的整合、开放和共享,构建产学研资用联动的服务体系,以促进校园的精细化治理。 智慧校园的核心建设任务包括数据标准体系和应用标准体系的建设,以及信息化安全与等级保护的实施。方案提出了一站式服务大厅和移动校园的概念,通过整合校内外资源,实现资源共享平台和产教融合就业平台的建设。此外,校园大脑的构建是实现智慧校园的关键,它涉及到数据中心化、数据资产化和数据业务化,以数据驱动业务自动化和智能化。 技术应用方面,方案提出了物联网平台、5G网络、人工智能平台等新技术的融合应用,以打造多场景融合的智慧校园大脑。这包括智慧教室、智慧实验室、智慧图书馆、智慧党建等多领域的智能化应用,旨在提升教学、科研、管理和服务的效率和质量。 在实施层面,智慧校园建设需要统筹规划和分步实施,确保项目的可行性和有效性。方案提出了主题梳理、场景梳理和数据梳理的方法,以及现有技术支持和项目分级的考虑,以指导智慧校园的建设。 最后,智慧校园建设的成功依赖于开放、协同和融合的组织建设。通过战略咨询、分步实施、生态建设和短板补充,可以构建符合学校特色的生态链,实现智慧校园的长远发展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值