Javascript-数组及应用

69 阅读8分钟

MDN 官网搜 Array.prototype 可以检索到所有array的方法.

数组 是一种数据类型,可以存储很多项,有顺序,很多项形成一个集合,这个集合就是数组.

数组的本质:数组是对象类型的一种特殊表现形式,因此创建的时候我们可以使用new方式来创建。

typeof运算符会返回数组的类型是object。typeof nameArr // "object"

数组中的元素可以使任意的数据类型:

arr = [{name = '孙悟空'}, {name = '沙和尚'}];    // 可以是对象

arr = [function(){}, function() {}];  	// 也可以是一个函数  调用:arr[0]( );

arr = [[1,2,3], [4,5,6], [7,8,9]];   // 数组中也可以放数组,这种数组称为"二维数组"

一、创建数组-3种方式

// 1、new Array() 创建数组对象
var arr = new Array();    // 空数组
arr[0] = 10;
arr[1] = 33; 

// 2、使用字面量创建数组【最常使用】
var arr = [ ] ;      // 空数组
 
// 3、使用构造函数创建数组
var arr= new Array(1,2,3,4,5,10);
console.log(arr);  // [1, 2, 3, 4, 5, 10]
arr = [10];			// 创建一个数组,数组中只有一个元素10 
arr = new Array(10); 	//	创建一个长度为10的数组

二、读取数组中的元素

// 语法: 数组[索引/下标]
arr[0]=""  // 根据数组下标,更改元素
console.log(arr[0]);  // 例:获取数组中的第一个元素
console.log(arr[arr.length -1]); // 获取数组中的最后一个元素
// 如果读取不存在的索引,它不会报错,而是返回undefined

// length 获取数组长度         例: arr.length
arr[arr.length] = 70 ; // 向数组的最后一个位置添加元素   语法:数组[数组.length] = 值;

三、遍历数组-for、for in、 for of

// 1. for循环遍历数组
// 获取数组中的每一项,并打印
var names = ['孙悟空', '猪八戒', '沙和尚', '唐僧'];
for (var i = 0; i < names.length ; i++) {
  console.log(names[i]);
}

// 反向遍历数组
var names = ['孙悟空', '猪八戒', '沙和尚', '唐僧'];
for (var i = names.length -1; i >= 0 ; i--) { 
  console.log(names[i]);
}

// 4. for循环-动态的给空数组增加元素
var arr = [];
for(var i = 0; i < 10; i++) { arr[i] = i;}
console.log(arr);    // 0,1,2,3,4,5,6,7,8,9
arr.length = 0;  // 清空数组


// 2. for in 方式
var heroArr = ['GreenJuPeople','BlackGuaFu','MetalXia'];
for(var index in heroArr){
  console.log(heroArr[index]); // 此处的index表示的数组的下标。并不是表示数组元素!
}

// 3. for of 方式
let restOfNum = [1, 2, 4];
let sum = 0;
for(let ele of restOfNum){
  sum += ele;
}
console.log(sum);

四、数组-常用方法(增删改查操作)

1.isArray()

// 判断是否为数组
// 返回值:如果是数组返回true,否则返回false。
var arr = []; 
Array.isArray(arr); // true
 
var arr = new Array(); 
var result = Array.isArray(arr); // true
 
var arr = [1, 2, 3]; 
var result = Array.isArray(arr); // true
 
var result = Array.isArray("an array"); 
document.write(result); // false  并不是一个数组,而是一个字符串

2.valueOf()

// 返回数组本身
// 语法:arr.valueOf()
var array = ["FrankenStein", true, 12, -5];	
document.writen(array.valueOf() === array ); // true 

3.toString()

// 数组转换成字符串
// 语法:arr.toString()
var girlFriends = ['ZhangTianAi','LiuShiShi','SomeOne'];
console.log(girlFriends.toString()); //ZhangTianAi,LiuShiShi,SomeOne

// str.split("=")  // 字符串转数组

4.push()

// 添加一个元素至数组最后一个,返回数组长度
// 语法:arr.push(item)
var girlFriends = ['张天爱', '李贞贤', '刘诗诗'];
console.log(girlFriends.push('someOne')); //4

5.pop()

// 删除数组的最后一个元素,并返回删除的这个元素
// 语法:arr.pop()
var girlFriends = ['张天爱', '李贞贤', '刘诗诗'];
console.log(girlFriends.pop());//刘诗诗

6.join(separator)

以给定的参数做分隔符,将所有的数组元素组成一个字符串,如果不提供参数,默认使用逗号分隔。

// 数组元素拼接成字符串
// 语法:arr.join(separator)   例 '' 空串、|、默认使用逗号分隔,
var girlFriends = ['张天爱', '李贞贤', '刘诗诗'];
console.log(girlFriends.join('|'));//张天爱|李贞贤|刘诗诗

7.shift()

// 删除数组中的第一个元素
// 并返回删除的这个元素
// 语法:arr.shift()
var girlFriends = ['张天爱', '李贞贤', '刘诗诗'];
console.log(girlFriends.shift()); // 张天爱

delete fruits[0]; // 把 fruits 中的首个元素改为 undefined  数组的'删除'

8.unshift()

// 添加元素至数组的第一个位置
// 语法:arr.unshift(item)  返回数组的长度
var girlFriends = ['李贞贤', '刘诗诗'];
console.log(girlFriends.unshift('张天爱')); // 3

9.reverse()

// 反序排列数组
// 语法:arr.reverse()
var girlFriends = [1, 2, 2];
console.log(girlFriends.reverse()); //[3, 2, 1]

10.slice(index1,index2)

// 截取数组
// 根据指定的【起始点】和【结束点】来对数组进行截取,并生成一个新数组.
// 新数组的内容是从起始点下标开始的元素到结束点下标的元素,但是不包括结束点下标的元素本身。
// 语法:arr.slice(index1,index2);	

var girlFriends = ['张天爱', '李贞贤', '刘诗诗'];
console.log(girlFriends.slice(1,2));// ["李贞贤

// ps:slice方法的参数可以是负值。-1代表最后一个元素,-2代表倒数第二个元素。
var girlFriends = ['ZhangTianAi','LiuShiShi','SomeOne'];
console.log(girlFriends.slice(-2,-1));//LiuShiShi
// pss:如果只写一个参数,则表示从当前坐标开始截取一直到最后一个元素。

11.splice(index,移除数量,新元素)

// 对数组进行增删改的操作
// 参数1:定义了应添加新元素的位置
// 参数2: 定义应删除多少元素
// 其它参数:可选,定义要添加的新元素,有没有新元素不是必要的。
// 返回值:包含已删除项的数组, 会修改原数组
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.splice(2, 2, "Lemon");   // 删除索引2开始的2个元素,添加一个新的元素
console.log(fruits)             // ["Banana", "Orange", "Lemon"]
fruits.splice(0, 1);            // 删除 fruits 中的第一个元素
fruits.splice(0, 0, "apple");   // 添加一个元素至数组第一个

12.sort()

// 语法:arr.sort(sortby) 
var arr = [1,100,40,25,38];
console.log(arr.sort());//[1, 100, 25, 38, 40]

13.indexOf(item,beginIndex)

// 返回元素在数组中的第一次出现的下标() 
// indexOf方法能够从前到后检索数组,并返回元素在数组中的第一次出现的下标,如果没有索引到则返回-1。indexOf第二个参数表示从第几个元素开始索引,是可选参数。
// 参数2:可以是负值。如果是-1则表示从最后一个元素开始向后查找,这种写法不推荐。
var numbers = [11,13,15,17,19,11];
console.log(numbers.indexOf(11));//0
console.log(numbers.indexOf(100));//-1

concat()  // 合并数组,不会改变原数组,返回合并后的新数组

14.arr.lastIndexOf(item,beginIndex)

// 从后向前检索数组, 返回元素在数组中的第一次出现的下标
// 语法:arr.lastIndexOf(item,beginIndex)
var numbers = [11,13,15,17,19,11];
console.log(numbers.lastIndexOf(11));//5
console.log(numbers.lastIndexOf(100));//-1

15.map()

// 遍历数组,并逐个操作每个元素
var arr = [1,2,3,4] // [2,3,4,5]
var newArr = arr.map(function(v){
  return v + 1;
});
console.log(newArr);

16.filter()

// 过滤元素
var arr = [{ name: "狗蛋" },{ name: "张全蛋" },{ name: "无关人士" }];

// 找出name带蛋字
ar newArr = arr.filter(function(v){
   return v.name.indexOf("蛋") > -1;
})
console.log(newArr);

17.reduce()

// 累加
// 典型案例:reduce()+递归 渲染左侧菜单
getMenuNodes = (menuList) => {
  // 得到当前请求的 path
  const path = this.props.location.pathname
  return menuList.reduce((pre, item) => {
    if (!item.children) {
      pre.push((
        <Menu.Item key={item.key}>
          <Link to={item.key}>
            <Icon type={item.icon}/><span>{item.title}</span>
          </Link>
        </Menu.Item>
      ))
    } else {
    pre.push((
      <SubMenu
        key={item.key}
        title={<span>
          <Icon type={item.icon}/>
          <span>{item.title}</span>
        </span>}>
        {this.getMenuNodes(item.children)}
      </SubMenu>
   ))
  // 如果当前请求路由与当前菜单的某个子菜单的 key 匹配, 将菜单的 key 保存为 openKey
  if(item.children.find(cItem => path.indexOf(cItem.key)===0)) {
    this.openKey = item.key
  }}
  return pre
}, []) }

18.find()

// 如果当前请求路由与当前菜单的某个子菜单的 key 匹配, 将菜单的 key 保存为 openKey
if(item.children.find(cItem => path.indexOf(cItem.key)===0)) {
  this.openKey = item.key
}}

// 自动打开子列表:查找一个与当前请求路径匹配的Item
const cItem = item.children.find(cItem => cItem.key === path)
if(cItem){
  this.openKey = item.key;
}

五、实例

1.求一组数的总和 和平均值

var numbers = [35, 12, 35, 90, 11, 12];
var sum = 0;
var avg;
for (var i =0; i < numbers.length; i++) {
  sum += numbers[i];
}
avg = sum / numbers.length;
console.log(sum);		// 195
console.log(avg);		// 32.5

2.求一组数中的最大值和最小值,以及所在位置

var numbers = [35, 12, 35, 90, 11, 14];
var max = numbers[0];
var min = numbers[0];
var maxIndex = 0;
var minIndex = 0;
for (var i = 0; i <numbers.length; i++) {
  if (max < numbers[i]) {
    max = numbers[i];
    maxIndex = i;
  }else if(min > numbers[i]) {
    min = numbers[i];
    minIndex = i;
  }
}
console.log(max, maxIndex, min, minIndex);

3.将字符串数组用 | 或其他符号分割

var arr = ['孙悟空', '猪八戒', '沙和尚', '唐僧'];
var separator = '|';
var str = arr[0];  // 往第二个元素之前加分隔符
for(var i = 1; i < arr.length; i++) {
  str += separator + arr[i];
}
console.log(str); // 孙悟空|猪八戒|沙和尚|唐僧

// ps:用join() 方法 更方便

4.要求将数组中的0 去掉,将不为0 的值存入一个新数组

let newArr = [];
let nums = [3, 5, 0, 7, 9, 0, 12, 0];
for (let i = 0; i < nums.length; i++) {
  if (nums[i] !== 0 ){
    newArr[newArr.length] = nums[i];
  }
}
console.log(newArr); // [3, 5, 7, 9, 12]

5.翻转数组, 即反着遍历数组存到新数组中去

let arr = [3, 5, 7, 9, 12];
let newArr = [];
for(let i = arr.length -1; i >= 0; i--) {
  newArr[newArr.length] = arr[i];
}
console.log(newArr); // [12, 9, 7, 5, 3]

6.冒泡排序 (从小到大排列)

let arr = [3, 8, 12, 6, 9, 2];
for(let i = 0; i < arr.length-1; i++) {
  for( let j = 0; j < arr.length-1-i; j++) {
    if(arr[j] > arr[j+1]) {
      let tem = arr[j];
      arr[j] = arr[j+1];
      arr[j+1] = tem;
 }}}
console.log(arr); //  [2, 3, 6, 8, 9, 12]

// 优化
let arr = [3, 8, 12, 6, 9, 2];
for(let i = 0; i < arr.length-1; i++) {	
  // 假设已经排好顺序了
  let isSort = true;
  for( let j = 0; j < arr.length-1-i; j++) {  
    if(arr[j] > arr[j+1]) {
       isSort = false; 	// 没有排好
       let tem = arr[j];
       arr[j] = arr[j+1];
       arr[j+1] = tem;
  } }
  if(isSort){ break; }	// 排好序后,跳出循环 
}
console.log(arr) // [2, 3, 6, 8, 9, 12]

五、其它

1.数组和伪数组

1.数组:var arr =[1, 2, 3];
arr.getSum();     arr.push();     arr.splice();

伪数组:getElementsByTagName();  不具备数组的那些方法

给伪数组里增加一项属性:
var obj = { 0: 100, 1: 10, 2: 20, 3: 30, length: 4 }
obj['4'] = 30;
obj.length++;   // 太麻烦

借用数组的方法:
Array.prototye.push.call(obj, 30); // 增加1项
Array.prototye.splice.call(obj, 0, 3);  // 删除数组中的前3项

2.判断数据类型

// 1.instanceof  变量 instanceof 对象
var arr = [1,2,3]
console.log(arr instanceof Array) // true

// 2. Object.prototype.toString.call() 
const arr = [1,2.3]
console.log(Object.prototype.toString.call(arr)==='[object Array]') // true


// 如何判断一个对象是否是数组?
var arr = [1, 2, 3]
arr.constructor === Array; // true 通过构造函数判断
arr instanceof Array; // true 通过prototype判断
Array.isArray(arr); // true 通过Array类的静态方法判断
Object.prototype.toString.call(arr) === "[object Array]"; // true 通过toString方法判断


// 我们现在来创建一个不是数组的对象
var arr = [1, 2, 3];
var obj = Object.create(arr);
obj.constructor === Array; //true 通过构造函数判断
obj instanceof Array; //true 通过prototype判断
Array.isArray(obj); //false 通过Array类的静态方法判断
Object.prototype.toString.call(obj) === "[object Array]"; //false 通过toString方法判断

只有Array.isArray和toString方法可以正确判断,所以以后别再用其他方法了~