Xin's blog Xin's blog
首页
  • 前端文章

    • HTML
    • CSS
    • JavaScript
    • Vue
    • 组件与插件
    • CSS扩展语言
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《JavaScript高级程序设计》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 《TypeScript 从零实现 axios》
    • 《Git》学习笔记
    • TypeScript笔记
    • JS设计模式总结笔记
  • 前端框架面试题汇总
  • 基本面试题
  • 进阶面试题
  • 其它
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 前后端联调
  • mock.js
  • 奇技淫巧
  • 分类
  • 标签
  • 归档
关于
GitHub (opens new window)

Xin

英雄可不能临阵脱逃啊~
首页
  • 前端文章

    • HTML
    • CSS
    • JavaScript
    • Vue
    • 组件与插件
    • CSS扩展语言
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《JavaScript高级程序设计》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 《TypeScript 从零实现 axios》
    • 《Git》学习笔记
    • TypeScript笔记
    • JS设计模式总结笔记
  • 前端框架面试题汇总
  • 基本面试题
  • 进阶面试题
  • 其它
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 前后端联调
  • mock.js
  • 奇技淫巧
  • 分类
  • 标签
  • 归档
关于
GitHub (opens new window)
  • HTML

  • CSS

  • JavaScript

    • 知识点

    • 方法

      • js能力提升1
      • js能力提升2
      • JS随机打乱数组
      • 判断是否为移动端浏览器
      • 将一维数组按指定长度转为二维数组
      • 防抖与节流函数
      • JS获取和修改url参数
      • js常用方法
      • js数据类型及类型判断
      • 用最简洁的代码去实现indexOf
      • 清空数组的方法
      • filter()方法过滤时如何保留假值?
      • 监听img元素是否加载完成
      • 树形结构转一维数组
      • 过滤数两个数组中重复的元素
      • 因为数据类型导致的排序错乱问题
        • 前言
        • 扩展
          • sort()方法
          • 冒泡排序
          • 选择排序
          • 快速排序
  • Vue

  • 组件与插件

  • css扩展语言

  • 学习笔记

  • 前端
  • JavaScript
  • 方法
ctrlwin
2022-02-24

因为数据类型导致的排序错乱问题

# 因为数据类型导致的排序错乱问题

# 前言

今天在码代码的时候遇到一个图片顺序错乱的bug,原因是后端给到的数据顺序是错乱的,所以前端需要根据数据的index值进行降序排序。数据结构大致如下:

  {
    "data": [
      {
        "description": "",
        "index": "1"
      },
      {
        "description": "",
        "index": "2"
      },
      {
        "description": "",
        "index": "5"
      },
      {
        "description": "",
        "index": "3"
      },
      {
        "description": "",
        "index": "4"
      },
      {
        "description": "",
        "index": "7"
      },
      {
        "description": "",
        "index": "6"
      },
      {
        "description": "",
        "index": "9"
      },
      {
        "description": "",
        "index": "8"
      },
      {
        "description": "",
        "index": "10"
      }
    ]
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

这个数据结构很简单啊,我们只需要按照index进行顺序排序就好了。

很快啊,三两下简单写了个冒泡排序,并且本地测试也都通过了,没问题赶紧提了代码。

然鹅,代码上线以后图片顺序还是错的...无语😭

先分析一下错误原因:

function bubbleSort(arr) {
  var len = arr.length;
  for (var i = 0; i < len; i++) {
    for (var j = 0; j < len - 1 - i; j++) {
      if (arr[j].index > arr[j + 1].index) { // <--就是这里出错了,没有考虑index的类型
        var temp = arr[j + 1];
        arr[j + 1] = arr[j];
        arr[j] = temp;
      }
    }
  }
  return arr;
}
1
2
3
4
5
6
7
8
9
10
11
12
13

问题就在于用于排序的index是String类型,而且本地测试的时候没有考虑到图片数量大于10的情况。在index小于10的时候,代码中的判断可以正常执行,但当index大于10的时候,字符串10如果直接比较会被拆分成1和0,然后分别和另一边比较。这时代码判断就有问题了,index为10会被排到index为2的前面。

不过,解决办法也很简单,将进行比较的值转成Number类型即可:

function bubbleSort(arr) {
  var len = arr.length;
  for (var i = 0; i < len; i++) {
    for (var j = 0; j < len - 1 - i; j++) {
-      if (arr[j].index > arr[j + 1].index) {
+      if (parseInt(arr[j].index) > parseInt(arr[j + 1].index)) {
        var temp = arr[j + 1];
        arr[j + 1] = arr[j];
        arr[j] = temp;
      }
    }
  }
  return arr;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

所以写代码的时候还是要多细心才行呀...

# 扩展

# sort()方法

使用sort()方法可以对数组对象进行排序可以这么写:

// 方法1
function sortTo(arr) {
  return arr.sort((a, b) => {
    return a['index'] - b['index'];
  })
}

sortTo(arr);
1
2
3
4
5
6
7
8

# 冒泡排序

function bubbleSort(arr) {
  var len = arr.length;
  for (var i = 0; i < len; i++) {
    for (var j = 0; j < len - 1 - i; j++) {
      if ((arr[j].index) > (arr[j + 1].index)) {        //相邻元素两两对比
        var temp = arr[j + 1];        //元素交换
        arr[j + 1] = arr[j];
        arr[j] = temp;
      }
    }
  }
  return arr;
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 选择排序

function selectionSort(arr) {
    var len = arr.length;
    var minIndex, temp;
    for (var i = 0; i < len - 1; i++) {
        minIndex = i;
        for (var j = i + 1; j < len; j++) {
            if (arr[j] < arr[minIndex]) {     //寻找最小的数
                minIndex = j;                 //将最小数的索引保存
            }
        }
        temp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = temp;
    }
    return arr;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 快速排序

function quickSort(arr, left, right) {
    var len = arr.length,
        partitionIndex,
        left = typeof left != 'number' ? 0 : left,
        right = typeof right != 'number' ? len - 1 : right;

    if (left < right) {
        partitionIndex = partition(arr, left, right);
        quickSort(arr, left, partitionIndex-1);
        quickSort(arr, partitionIndex+1, right);
    }
    return arr;
}

function partition(arr, left ,right) {     //分区操作
    var pivot = left,                      //设定基准值(pivot)
        index = pivot + 1;
    for (var i = index; i <= right; i++) {
        if (arr[i] < arr[pivot]) {
            swap(arr, i, index);
            index++;
        }        
    }
    swap(arr, pivot, index - 1);
    return index-1;
}

function swap(arr, i, j) {
    var temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

精简版:

function quickSort(array) {
  if (array.length < 2) return array; // 递归出口
  let pivot = array[array.length - 1] // 取分界点
  // 取分界点左边的数组(不包括最后一位,最后一位是分界点)
  let left = array.filter((v, i) => v <= pivot && i != array.length - 1) 
  let right = array.filter(v => v > pivot) // 取分界点右边的数组
  return [...quickSort(left), pivot, ...quickSort(right)] // 递归排序,合并结果
}
1
2
3
4
5
6
7
8

参考文章:js十大排序算法 (opens new window)

手写算法并记住它:快速排序(5行代码简单版) (opens new window)

在GitHub上编辑 (opens new window)
#js
上次更新: 4/11/2022, 3:09:54 PM

← 过滤数两个数组中重复的元素 filters过滤器的使用→

最近更新
01
createElement函数创建虚拟DOM
05-26
02
clipboard 剪切板属性
05-26
03
vue的权限管理
05-16
更多文章>
Theme by Vdoing | Copyright © 2021-2022 Xin | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×