第六课:数组的扩展与修复

1.indexOf和lastIndexOf方法:

因为IE7在数组对象上使用indexOf会报错,所以需要重写一个兼容性的。

Array.prototype.lastIndexOf(item,index){

  var n = this.length,i = (index==null||index>n-1)?n-1:index;

  if(i < 0) i = n+i;

  for(;i>=0;i--)

    if(this[i] === item)   //全等判断,indexOf,lastIndexOf

      return i;

  return -1;

}

2.shuffle方法:对数组进行洗牌。

function shuffle(target){

  var i = target.length, j ,temp;

  for(;i>0;j=parseInt(Math.random() * i), x = target[--i],target[i] = target[j],target[j]=x){}

     //假设length=10,那么Math.random()*10->[0,10),parseInt后,[0,9],随机的选择一个与数组最后一项交换。第二次循环,[0,8],与数组的倒数第二项交换。

  return target;

}

3.数组的平坦化处理:flatten,返回一个一维数组

function flatten(arr){

  var result = [];

  arr.forEach(function(item){

    if(Array.isArray(item))   result.concat(flatten(item));

    else  result.push(item);

  });

  return result;

}

4.unique方法:对数组去重操作

此方法,面试官最喜欢问了,因为它有多种实现方法,最普通的是两个for循环。一般知道的最多的是使用一个对象a,然后一个for循环数组arr,每次if(a[arr[i]])是否存在,不存在则push到你新定义的数组result中。存在就证明,重复,因此不用push到result中。这种方案,针对"123",123,会认为相同的,其实一个是字符串,一个是数字,不应该认为是相同的。

所以就出现了以下方法:[1,"1","1"]

if ((typeof obj[array[i]]) != (typeof array[i]) || obj[array[i]] != array[i]) {

  a.push(array[i]);

  obj[array[i]] = array[i];

}

//首先判断类型是否相同,如果相同,就判断他们的值是否相等,不相等就存进去,相等就证明之前已经存在这个值了。

如果类型不相同,这里存在两种情况,

第一种情况,obj之前已经存了此数据了,比如:obj[123] = 123,现在array[i] = "123",这时,typeof obj[array[i]])是数字,而typeof array[i]是字符串,因此存入数组中。

第二种情况是obj还没存此数据,比如:array[i] = "123",obj["123"] = undefind,这时typeof obj[array[i]])就是typeof undefined = undefined,不等于typeof array[i],存入数组中。

此种方法,可以解决字符串和数字相同的情况,但是无法解决对象相同的情况。比如:a = {1:2}, b ={2:1};

第一次循环时,typeof obj[a] = undefined,typeof a = Object。存入obj[a] =a.其实就是obj[Object] = a;

第二次循环时,typeof obj[b] 等于typeof obj[Object]其实就是typeof a = object,typeof b = object.因此进入到obj[array[i]] != array[i]|,也就是obj[b]->obj[Object]->a != b,因此存入

obj[b] = b;也就是obj[Object] = b;覆盖了之前的obj[Object] = a;

这种情况下,就会出现所有的对象,都只会存最后一个对象值。

当考虑对象时,我就会使用以下这种方法:

for(var i = 0; i < temp.length; i++){                for(var j = i + 1; j < temp.length; j++){                        if(temp[i] === temp[j]){                                temp.splice( j, 1 );                                j--;                        }                }        } return temp;

5.数组排序:sort方法,如果要排序的是对象,可以自己写一个compare(a,b){if(a.age>b.age) return 1;else return -1;},A.sort(compare).

6.min返回数组最小值:return Math.min.apply(0,array);

7.unshift在ie6,7下不返回数组长度。

if([].unshift(1)!==1)   //往空数组中从前面添加一项,其他浏览器会返回1,而IE6,7不会返回数组长度。这时就执行if语句

{

  var _unshift = Array.prototype.unshift;      //函数劫持。

  Array.prototype.unshift = function(){

    _unshift.apply(this,arguments);

    return this.length;

  }

}

8.splice在一个参数的情况下,IE8以及以下版本默认第二个参数为0,而其他浏览器是数组长度。

if([1,2,3].splice(1).length == 0)   //IE8以及以下版本会等于0,其他版本会等于3,进入if里面

{

  var _splice = Array.prototype.splice;

  Array.prototype.splice = function(a){

    if(arguments.length == 1)   //如果只有一个参数时

    {

      return _splice.call(this,a,this.length);

    }else{

      return _splice.apply(this,arguments);

    }

  }

}

这个方法会改变数组的选项,因此数组的push,pop,shift,unshift(这几个方法也会修改数组的选项)都会调用这个方法来实现。

这里有一个地方需要注意:

var color = new Array(‘red‘,‘blue‘,‘yellow‘,‘black‘);
var color2 = color.splice(2,0,‘brown‘,‘pink‘);
alert(color); // red,blue,brown,pink,yellow,black,在yellow选项上,开始操作,如果删除为0,则添加的选项是在yellow之前插入。切记。

这里请大家去看下splice和slice的区别,返回值,以及对原数组的影响。 面试官会问。

加油!

时间: 2024-08-10 00:07:19

第六课:数组的扩展与修复的相关文章

第十六课 数组的引入 【项目1-5】

第十六课 数组的引入 项目一 [数组大折腾] (1)创建一个有20个元素的整型数组,通过初始化,为数组中的前10个元素赋初值,然后通过键盘输入后10个元素的值,从前往后(从第0个到第19个)输出数组中元素的值,每5个元素换一行. [cpp] view plain copy print? int main( ) { int a[20]={...};  //初始化前10个元素 //键盘输入后10个元素的值 //由前往后输出数组中所有元素的值 printf("由前往后,数组中的值是:\n")

PHP第六课 数组的用法

学习概要: *了解基本的数组函数的使用 *懂得数组的遍历 *了解超全局数组的基本关系与使用 数组 1.数组定义和遍历 2.数组函数 数组定义: $arr=array(1,2,3);//索引数组,下标全是数字 $arr=array("name"=>"user1","age"=>"30");//关联数组,下标中包含字母 //下标只有两种,要么是字母,要是是不带双引号的数字 <?php $arr=array(&qu

ES6--字符串、正则、数值、数组的扩展

三.字符串的扩展 字符编码 JavaScript内部,字符以UTF-16的格式储存,每个字符固定为2个字节.对于那些需要4个字节储存的字符(Unicode码点大于0xFFFF的字符),JavaScript会认为它们是两个字符.然而汉字往往就是4个字节存储,ES6之前处理起来有些麻烦. 示例:字符编码 var ChineseName = "李刚"; var EnglishName = "ligang"; ChineseName.codePointAt(1); // 0

从js的repeat方法谈js字符串与数组的扩展方法

js将字符串重复N次的repeat方法的8个版本 /* *@desc: 将一个字符串重复自身N次 */ //版本1:利用空数组的join方法 function repeat(target, n) { return (new Array(n + 1)).join(target); } //版本2:之所以要创建一个带length属性的对象 是因为要调用数据的原型方法,需要指定call的第一个参数为类数组对象 //类数组对象的必要条件是其length属性的值为非负数 function repeat(t

第七课:数值以及函数的扩展和修复

1.数值扩展和修复 toFixed(num) 方法可把 Number 四舍五入为指定小数位数的数字.num必需,规定小数的位数,是 0 ~ 20 之间的值,包括 0 和 20,有些实现可以支持更大的数值范围.如果省略了该参数,将用 0 代替.返回 NumberObject 的字符串表示,不采用指数计数法,小数点后有固定的 num 位数字.如果必要,该数字会被舍入,也可以用 0 补足,以便它达到指定的长度.如果 num 大于 le+21,则该方法只调用 NumberObject.toString(

NeHe OpenGL教程 第三十六课:从渲染到纹理

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第三十六课:从渲染到纹理 放射模糊和渲染到纹理: 如何实现放射状的滤镜效果呢,看上去很难,其实很简单.把渲染得图像作为纹理提取出来,在利用OpenGL本身自带的纹理过滤,就能实现这种效果,不信,你试试. 嗨,我是Dario Corn

OpenGL教程翻译 第十六课 基本的纹理贴图

OpenGL教程翻译 第十六课 基本的纹理贴图 原文地址:http://ogldev.atspace.co.uk/(源码请从原文主页下载) Background 纹理贴图就是将任意一种类型的图片应用到3D模型的一个或多个面.图片(也可以称之为纹理)内容可以是任何东西,但是他们一般都是一些比如砖,叶子,地面等的图案,纹理贴图增加了场景的真实性.例如,对比下面的两幅图片. 为了进行纹理贴图,你需要进行三个步骤:将图片加载到OpenGl中,定义模型顶点的纹理坐标(以对其进行贴图),用纹理坐标对图片进行

2018-08-24 第三十六课

第三十六课 非关系统型数据库-mangodb 目录 二十四 mongodb介绍 二十五 mongodb安装 二十六 连接mongodb 二十七 mongodb用户管理 二十八 mongodb创建集合.数据管理 二十九 php的mongodb扩展 三十 php的mongo扩展 三十一 mongodb副本集介绍 三十二 mongodb副本集搭建 三十三 mongodb副本集测试 三十四 mongodb分片介绍 三十五 mongodb分片搭建 三十六 mongodb分片测试 三十七 mongodb备份

【C语言探索之旅】 第二部分第六课:创建你自己的变量类型

0 内容简介 1.课程大纲 2.第二部分第六课: 创建你自己的变量类型 3.第二部分第七课预告: 文件读写 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编写三个游戏. C语言编程基础知识 什么是编程? 工欲善其事,必先利其器 你的第一个程序 变量的世界 运算那点事 条件表达式 循环语句 实战:第一个C语言小游戏 函数 练习题 习作:完善第一个C语言小游戏 C语言高级技术 模块化编程 进击的指针,C语言王牌 数组 字符串 预处理 创建你自己的变量