JavaScript常用数组算法小结


Posted in Javascript onFebruary 13, 2016

今天抽点时间把javascript中的一些常用的数组算法做一下总结,以方便大家面试笔试或者日常开发过程中用到。其中部分算法来自网络,这里做了下汇总整理。文章末尾我会把参考的来源附上去,如果直接看算法比较枯燥的可以到参考文献里去看,讲解的非常不错。

一、数组去重

方法1:

//利用数组的indexOf方法
function unique (arr) {
 var result = []; 
 for (var i = 0; i < arr.length; i++)
 {
  if (result.indexOf(arr[i]) == -1) result.push(arr[i]);
 }
 return result;
}

方法2:

//利用hash表,可能会出现字符串和数字一样的话出错,如var a = [1, 2, 3, 4, '3', 5],会返回[1, 2, 3, 4, 5]
function unique (arr){
  var hash = {},result = []; 
  for(var i = 0; i < arr.length; i++)
  {
    if (!hash[arr[i]]) 
    {
      hash[arr[i]] = true; 
      result.push(arr[i]); 
    }
  }
  return result;
}

方法3:

//排序后比较相邻,如果一样则放弃,否则加入到result。会出现与方法2一样的问题,如果数组中存在1,1,'1'这样的情况,则会排错

function unique (arr) {
  arr.sort();
  var result=[arr[0]];
  for(var i = 1; i < arr.length; i++){
    if( arr[i] !== arr[i-1]) {
      result.push(arr[i]);
    }
  }
  return result;
}

方法4:

//最简单但是效率最低的算法,也不会出现方法2和方法3出现的bug
function unique (arr) {
  if(arr.length == 0) return;
  var result = [arr[0]], isRepeate;
  for( var i = 0, j = arr.length; i < j; i++ ){
    isRepeate = false;
    for( var k = 0, h = result.length; k < h; k++){
      if(result[k] === arr[i]){
        isRepeate = true;
        break;
      }
      if(k == h) break;
    }
    if( !isRepeate ) result.push(arr[i]);
  }
  return result;
}

方法5:

//此方法充分利用了递归和indexOf方法,感谢网友@真爱像深蓝
var unique = function (arr, newArr) {
   var num;

   if (-1 == arr.indexOf(num = arr.shift())) newArr.push(num);

   arr.length && unique(arr, newArr);
}

二、数组顺序扰乱

方法1:

//每次随机抽一个数并移动到新数组中
function shuffle(array) {
  var copy = [],
    n = array.length,
    i;
  // 如果还剩有元素则继续。。。
  while (n) {
    // 随机抽取一个元素
    i = Math.floor(Math.random() * array.length);
    // 如果这个元素之前没有被选中过。。
    if (i in array) {
      copy.push(array[i]);
      delete array[i];
      n--;
    }
  }
  return copy;
};

方法2:

//跟方法1类似,只不过通过splice来去掉原数组已选项
function shuffle(array) {
  var copy = [],
    n = array.length,
    i;
  // 如果还剩有元素。。
  while (n) {
    // 随机选取一个元素
    i = Math.floor(Math.random() * n--);
    // 移动到新数组中
    copy.push(array.splice(i, 1)[0]);
  }
  return copy;
}

方法3:

//前面随机抽数依次跟末尾的数交换,后面依次前移,即:第一次前n个数随机抽一个跟第n个交换,第二次前n-1个数跟第n-1个交换,依次类推。
function shuffle(array) {

var m = array.length,
  t, i;
// 如果还剩有元素…
while (m) {
  // 随机选取一个元素…
  i = Math.floor(Math.random() * m--);
  // 与当前元素进行交换
  t = array[m];
  array[m] = array[i];
  array[i] = t;
}
return array; }

三、数组判断

方法1:

//自带的isArray方法
var array6 = [];
Array.isArray(array6 );//true

方法2:

//利用instanceof运算符
   var array5 = [];
   array5 instanceof Array;//true

方法3:

//利用toString的返回值
   function isArray(o) {
     return Object.prototype.toString.call(o) === '[object Array]'; 
   }

四、数组求交集

方法1:

//利用filter和数组自带的indexOf方法
   array1.filter(function(n) {
   return array2.indexOf(n) != -1 });

五、数组求并集

方法1:

//方法原理:连接两个数组并去重
   function arrayUnique(array) {
     var a = array.concat(array2);
     for(var i=0; i<a.length; ++i) {
       for(var j=i+1; j<a.length; ++j) {
         if(a[i] === a[j])
           a.splice(j--, 1);
       }
     }
     return a;
   };

六、数组求差集

方法1:

//利用filter和indexOf方法
   Array.prototype.diff = function(a) {
     return this.filter(function(i) {
      return a.indexOf(i) < 0;
      });
};

上面的方法1只能求出一个数组相对另一个数组的差集,比如array1.diff(array2),只能求出array1相对array2的差集,如果希望将两个数组不同的值都获取到,可以array1.diff(array2).concat(array2.diff(array1)),也可以使用方法2

方法2

var array1 = new Array(55,55,88,6,68,109,55,33,6,2,1);
   var array2 = [55,88,99,69,109,55,33,6,2,1];
   var diffArr = array1.concat(array2);
   
   var diff = diffArr.filter(function(i) {
           return array1.indexOf(i) < 0||array2.indexOf(i) < 0;
       });
   
   console.log( diff );

暂时汇总了这点儿,有待后续补充。欢迎大家补充,如有问题,敬请留言,共同探讨和进步,^_^

Javascript 相关文章推荐
JS Pro-深入面向对象的程序设计之继承的详解
May 07 Javascript
js中arguments,caller,callee,apply的用法小结
Jan 28 Javascript
jQuery操作表格(table)的常用方法、技巧汇总
Apr 12 Javascript
JavaScript中cookie工具函数封装的示例代码
Oct 11 Javascript
原生JS实现图片翻书效果
Feb 16 Javascript
jQuery实现键盘回车搜索功能
Jul 25 jQuery
addeventlistener监听scroll跟touch(实例讲解)
Aug 04 Javascript
使用SVG基本操作API的实例讲解
Sep 14 Javascript
vue打包的时候自动将px转成rem的操作方法
Jun 20 Javascript
JavaScript解析及序列化JSON的方法实例分析
Jan 04 Javascript
ES6基础之字符串和函数的拓展详解
Aug 22 Javascript
微信小程序webSocket的使用方法
Feb 20 Javascript
Javascript 字符串模板的简单实现
Feb 13 #Javascript
javascript基础知识分享之类与函数化
Feb 13 #Javascript
JavaScript正则表达式的分组匹配详解
Feb 13 #Javascript
js HTML5 Ajax实现文件上传进度条功能
Feb 13 #Javascript
js随机生成26个大小写字母
Feb 12 #Javascript
jquery实现具有嵌套功能的选项卡
Feb 12 #Javascript
基于jquery实现动态竖向柱状条特效
Feb 12 #Javascript
You might like
一个SQL管理员的web接口
2006/10/09 PHP
php、mysql查询当天,查询本周,查询本月的数据实例(字段是时间戳)
2017/02/04 PHP
php工具型代码之印章抠图
2018/07/18 PHP
PHP token验证生成原理实例分析
2019/06/05 PHP
JQuyer $.post 与 $.ajax 访问WCF ajax service 时的问题需要注意的地方
2011/09/20 Javascript
远离JS灾难css灾难之 js私有函数和css选择器作为容器
2011/12/11 Javascript
javascript调试过程中找不到哪里出错的可能原因
2013/12/16 Javascript
jQuery实现自动调整字体大小的方法
2015/06/15 Javascript
Bootstrap每天必学之基础排版
2015/11/20 Javascript
js 自带的 map() 方法全面了解
2016/08/16 Javascript
vue.js实现请求数据的方法示例
2017/02/07 Javascript
Bootstrap table 定制提示语的加载过程
2017/02/20 Javascript
详解Vue2.x-directive的学习笔记
2017/07/17 Javascript
详解vue 组件之间使用eventbus传值
2017/10/25 Javascript
JavaScript Date对象应用实例分享
2017/10/30 Javascript
JS与SQL方式随机生成高强度密码示例
2018/12/29 Javascript
React学习之受控组件与数据共享实例分析
2020/01/06 Javascript
如何实现iframe父子传参通信
2020/02/05 Javascript
如何基于viewport vm适配移动端页面
2020/11/13 Javascript
[01:18]PWL开团时刻DAY10——一拳超人
2020/11/11 DOTA
linux系统使用python监测系统负载脚本分享
2014/01/15 Python
Python获取网页上图片下载地址的方法
2015/03/11 Python
使用简单工厂模式来进行Python的设计模式编程
2016/03/01 Python
基于Python3 逗号代码 和 字符图网格(详谈)
2017/06/22 Python
Django框架实现分页显示内容的方法详解
2019/05/10 Python
Python3 实现爬取网站下所有URL方式
2020/01/16 Python
python3连接MySQL8.0的两种方式
2020/02/17 Python
canvas像素画板的实现代码
2018/11/21 HTML / CSS
HTML5单页面手势滑屏切换原理
2016/03/21 HTML / CSS
2014年学校团委工作总结
2014/12/20 职场文书
大学生预备党员自我评价
2015/03/04 职场文书
社区扶贫帮困工作总结
2015/05/20 职场文书
活动主持人开场白
2015/05/28 职场文书
2019年工作总结范文
2019/05/21 职场文书
MySQL Server层四个日志的实现
2022/03/31 MySQL
古见同学有交流障碍症 第二季宣传CM公开播出
2022/04/11 日漫