js内功修炼-数组篇

思考几个个问题:

  • 数组的构造器有哪些?
  • 数组的方法?
  • 数组遍历的方法?
  • forEach 、for … in、for … of 三者的区别?

数组的构造器

常见创建数组的两种方式

  • Array构造器
  • 函数自变量
  1. Array构造器 var A = new Array (arg1, arg2, …)

new Array (arg1, arg2, …) 会根据传入的参数,按顺序依次成为数组的第0-N项

注意两点:

第一,当有且仅有一个参数,参数值不能超过 32 位无符号整型,即需要小于 2 的 32 次方(最大为 Math.pow(2,32));
第二,当有且仅有一个参数l,参数值不超过 32 位无符号整型时,返回的是一个长度为参数的空数组
复制代码

var a = new Array(1, 2, 3, 4)
var b = new Array(4)
var c = new Array('4')
var d = new Array()


console.log(a)  // [1, 2, 3, 4]
console.log(b)  // [empty * 4]
console.log(c)  // ["4"]
console.log(d)	// []
复制代码
  1. 函数自变量 var a = []

var a = [arg1, arg2, arg3, …] 会根据传入的参数,按顺序依次成为数组的第0-N项,无法直接返回指定长度的空数组,通过var a = [], a.length=4 的方式返回指定长度为4的空数组

var a = [1, 2, 3, 4]
var b = [4]
var c = ['4']
var d = []
var e = []
e.length = 4

console.log(a)  // [1, 2, 3, 4]
console.log(b)  // [4]
console.log(c)  // ["4"]
console.log(d)  // []
console.log(e)  // [empty * 4]
复制代码

es6新增的构造方法

  • Array.of
  • Array.from
  1. Array.of (arg1, arg2, …)与 new Array (arg1, arg2, …)的区别在于,当参数为有且仅有一个的数字时,Array.of 返回的是[arg1]数组, new Array返回的是[empty * arg1]的空数组,也就是说 Array.of 和函数自变量的返回结果一致

  2. Array.from / Array.prototype.slice.call() / [].slice.call()的作用 将两类对象转换成数。这两类对象分别为:

(1)可遍历(interable)的对象(包括 Set 和 Map)

(2)典型的“类似数组的对象”是函数的arguments对象,以及大多数 DOM 元素集,还有字符串。类数组的本质是拥有length属性,只要有length属性就可以用Array.from转换成数组

Array.from(arg1, arg2, arg3)接收三个参数, 第一个参数为类数组对象,必选参数,第二个和第三个为可选参数,分别为回调函数和回调函数的this,函数回调也可以直接使用箭头函数,就不需要第三个参数来指定this了,回调函数中可对返回的数组进行处理。返回新的数组,不改变原对象。

var obj = {0: 'a', 1: 'b', 2:'c', length: 3};
Array.from(obj, function(value, index){
  console.log(value, index, this, arguments.length);
  return value.repeat(3);   //必须指定返回值,否则返回 undefined
}, obj);
复制代码

image.png

var a = Array.from('abc');       
var b = Array.from(new Set(['abc', 'def'])); 
var c = Array.from(new Map([[1, 'ab'], [2, 'de']])); 

var obj = {0: 'a', 1: 'b', 2:'c', length: 3};
var d = Array.from(obj, (value) => value.repeat(3));

console.log(a)  // ["a", "b", "c"]
console.log(b)  // ["abc", "def"]
console.log(c)  // [[1, "ab"], [2, "de"]]
console.log(d)	// ["aaa", "bbb", "ccc"]
复制代码

数组的方法

改变自身的方法

pop、push、reverse、shift、sort、splice、unshift,以及两个 ES6 新增的方法 copyWithin 和 fill。

//  pop、push、shift、unshift
var a = [1, 2, 3, 4, 5]
var aa = a.pop()  

var b = [1, 2, 3, 4, 5]
var bb = b.push(9)  

var c = [1, 2, 3, 4, 5]
var cc = c.shift()  

var d = [1, 2, 3, 4, 5]
var dd = d.unshift(0)  

// pop 删除数组最后一个数据,返回删除的数据
console.log(a)   // [1, 2, 3, 4]
console.log(aa)  // 5

// push 数组末尾增加一个元素,返回增加后数组的长度
console.log(b)   // [1, 2, 3, 4, 5, 9]
console.log(bb)  // 9

// shift 删除数组第一个元素,返回删除的元素
console.log(c)  // [2, 3, 4, 5]
console.log(cc) // 1

// unshift 数组开始增加一个元素,返回增加后数组的长度
console.log(d)   // [0, 1, 2, 3, 4, 5]
console.log(dd)  // 6
复制代码
// splice、reverse、sort
var e = [1, 2, 3, 4, 5]
var ee = e.splice(2, 2)  

var f = [1, 2, 3, 4, 5]
var ff = f.reverse()

var g = [1, 4, 5, 2, 3]
var gg = g.sort()

// splice(start, len) 删除数组中的元素,start开始位置的index, len删除几个,返回一个数组,由删除的元素组成
console.log(e)  // [1, 2, 5]
console.log(ee) // [3,4]

// reverse 数组翻转,返回翻转后的数组
console.log(f)   // [5, 4, 3, 2, 1]
console.log(ff)  // [5, 4, 3, 2, 1]

// sort 数组排序
console.log(g)  // [1, 2, 3, 4, 5]
console.log(gg) // [1, 2, 3, 4, 5]
复制代码
// copyWithin、fill
var h = [1, 2, 3, 4, 5]
var i = [1, 2, 3, 4, 5]

var hh = h.copyWithin(1, 2)
var ii = i.copyWithin(1, 2, 3)


var j = [1, 2, 3, 4, 5]
var k = [1, 2, 3, 4, 5]

var jj = j.fill(6, 1)
var kk = k.fill(6, 1, 2)

// copyWithin(target, start, end) 数组中start-end位置值,复制到以target为开始的位置
console.log(hh)
console.log(ii)

// fill(value, start, end) 采用一默认值填初始化数组,可以指定填充的位置
console.log(jj)
console.log(kk)
复制代码

不改变自身的方法

concat、join、slice、toString、toLocaleString、indexOf、lastIndexOf、未形成标准的 toSource,以及 ES7 新增的方法 includes。

// concat方法
var array = [1, 2, 3];
var array2 = array.concat(4,[5,6],[7,8,9]);
console.log(array2); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(array); // [1, 2, 3], 可见原数组并未被修改

// join方法
var array = ['We', 'are', 'Chinese'];
console.log(array.join()); // "We,are,Chinese"
console.log(array.join('+')); // "We+are+Chinese"

// slice方法
var array = ["one", "two", "three","four", "five"];
console.log(array.slice()); // ["one", "two", "three","four", "five"]
console.log(array.slice(2,3)); // ["three"]

// toString方法
var array = ['Jan', 'Feb', 'Mar', 'Apr'];
var str = array.toString();
console.log(str); // Jan,Feb,Mar,Apr

// tolocalString方法
var array= [{name:'zz'}, 123, "abc", new Date()];
var str = array.toLocaleString();
console.log(str); // [object Object],123,abc,2016/1/5 下午1:06:23

// indexOf方法
var array = ['abc', 'def', 'ghi','123'];
console.log(array.indexOf('def')); // 1

// includes方法
var array = [-0, 1, 2];
console.log(array.includes(+0)); // true
console.log(array.includes(1)); // true
var array = [NaN];
console.log(array.includes(NaN)); // true
复制代码

数组遍历的方法

forEach、every、some、filter、map、reduce、reduceRight,以及 ES6 新增的方法 entries、find、findIndex、keys、values。

// 数组遍历
var arr = [1, 2, 3, 4, 5]

var a = arr.every((item) => item < 10)
var b = arr.some((item) => item < 2)
var c = arr.filter((item) => item < 2)
var d = arr.map((item) => item < 2)
var e = arr.forEach((item) => item < 2)
var f = arr.reduce((pre, next) => pre * next)

// 数组遍历返回值
console.log(a)  // true
console.log(b)  // true
console.log(c)  // [1]
console.log(d)  // [true, false, false, false, false]
console.log(e)  // undefined
console.log(f)  // 120
复制代码
var arr = [1, 2, 3, 4, 5]

var a = arr.find((item) => item > 3)
var b = arr.findIndex((item) => item < 2)
var c = arr.keys()
var d = arr.entries()
var e = arr.values()

console.log(a)      // 4
console.log(b)			// 0
console.log(...c)   // 0 1 2 3 4
console.log(...d)   // [0, 1] [1, 2] [2, 3] [3, 4] [4, 5]
console.log(...e)   // 1 2 3 4 5
复制代码

forEach 、for … in、for … of 三者的区别

  1. 对数组的每一个元素执行一次提供的函数(不能使用return、break等中断循环),不改变原数组,无返回值undefined。
  2. 循环遍历的值都是数据结构的键值,for in也可以循环数组但是特别适合遍历对象
  3. for of 是ES6中新增加的语法,用来循环获取一对键值对中的值,一个数据结构只有部署了 Symbol.iterator 属性, 才具有 iterator接口可以使用 for of循环。例子中的obj对象没有Symbol.iterator属性 所以会报错。

哪些数据结构部署了 Symbol.iteratoer属性了呢?

  • 数组 Array
  • Map
  • Set
  • String
  • arguments对象
  • Nodelist对象, 就是获取的dom列表集合

数组扁平化

1.ES6的flat

const arr = [1, [2, 3, [4, 5]]]
arr.flat(Infinity) 
复制代码

2.递归

const arr = [1, [2, 3, [4, 5]]]

const flat = (arr) => {
	let result = []
  for (let i = 0, len = arr.length; i < len; i++ ) {
    Array.isArray(arr[i]) ? result = [...result, ...flat(arr[i])] : result.push(arr[i])
  }
  return result
}

flat(arr)
复制代码

3.reduce + 递归

const arr = [1, [2, 3, [4, 5]]]

const flat = (arr) => {
  if (!Array.isArray(arr)) return
  return arr.reduce((prev, curr) => prev.concat(Array.isArray(curr) ? flat(curr) : curr), [])
}

flat(arr)
复制代码

4.扩展运算符 + 迭代

const arr = [1, [2, 3, [4, 5]]]

const flat = (arr) => {
  while(arr.some((item) => Array.isArray(item))) {
  	arr = [].concat(...arr)
  }
  return arr
}

flat(arr)
复制代码

5.序列化 + 正则

const arr = [1, [2, 3, [4, 5]]]

const flat = (arr) => {
  return JSON.parse(`[${JSON.stringify(arr).replace(/(\[|\])/g, '')}]`)
}

flat(arr)
复制代码

数组去重

1.ES6 Set

const arr = [1, 2, 1, 2, 3 ,4, 5]

const unique = (arr) => {
  return Array.from(new Set(arr))  // return [...new Set(arr)]
}

unique(arr)
复制代码

2.利用indexOf、includes

const arr = [1, 2, 1, 2, 3 ,4, 5]

const unique = (arr) => {
  let result = []
  for (let i of arr) {
  	if (result.indexOf(i) === -1) {  // if (!result.includes(i))
    	result.push(i)
    }
  }
  return result
}

unique(arr)


复制代码

3.for 循环嵌套

const arr = [1, 2, 1, 2, 3 ,4, 5]

const unique = (arr) => {
  for (let i = 0, len = arr.length; i < len; i++) {
  	for(let j = i + 1, len = arr.length; j < len; j++) {
      if(arr[i] === arr[j]) {
      	arr.splice(i, 1)
        j--
      }
    }
  }
  return arr
}

unique(arr)
复制代码

4. filter + indexOf

const arr = [1, 2, 1, 2, 3 ,4, 5]

const unique = (arr) => {
  return arr.filter((item, index) => arr.indexOf(item) === index)
}

unique(arr)
复制代码

5.reduce + includes

const arr = [1, 2, 1, 2, 3 ,4, 5]

const unique = (arr) => {
  return arr.reduce((prev, curr) => prev.includes(curr) ? prev : [...prev, curr], [])
}

unique(arr)
复制代码

6.sort


const arr = [1, 2, 1, 2, 3 ,4, 5]

const unique = (arr) => {
  arr = arr.sort()
  let result = [arr[0]]
  for (let i = 1, len = arr.length; i < len; i++) {
  	if (arr[i] !== arr[i-1]) {
      result.push(arr[i])
    }
  }
  return result
}

unique(arr)
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享