闲来无事将数组的常用方法实现了一遍,并没有想象的那么难,注意好临界情况,和特殊值的处理就好了,其中splice()方法是实现上最复杂的一个。建议前端开发者可以将splice()手动实现一遍,会有意想不到的收获。在思考的过程中可以讲相似方法,通过传不同的参数提取为公共方法。
查找元素
indexOf()
用来查找传进来的参数在目标数组中是否存在,没有找到返回-1
手动实现:
{
function arrIndexOfHandle(arr, item) {
let index = -1;
for (let i = 0; i < arr.length; i++) {
if (arr[i] === item) {
return index = i // 找到目标元素,立即返回元素的序列号,终止循环
}
}
return index
}
let arr = ['gao', 'bing', 1, 3, 23, 'gao'];
console.log(arrIndexOfHandle(arr, 'gao')) // 0
console.log(arrIndexOfHandle(arr, 3)) // 3
console.log(arrIndexOfHandle(arr, 33)) // -1
}
lastIndexOf()
返回相同元素中最后一个元素的索引,没有找到返回-1
{
function arrLastIndexOfHandle(arr, item) {
let index = -1;
let LEN = arr.length;
for (var i = LEN; i >= 0; i--) {
if (arr[i] === item) {
index = i
return index // 倒序对比的时候,找到目标元素,就返回元素的序列号,终止循环
}
}
return index
}
let arr = ['gao', 'bing', 1, 3, 23, 'gao', 3];
console.log('gao:' + arrLastIndexOfHandle(arr, 'gao')) // 5
console.log('3:' + arrLastIndexOfHandle(arr, 3)) // 6
console.log('33:' + arrLastIndexOfHandle(arr, 33)) // -1
}
indexOf和lastIndexOf方法有很多重复的部分,如何精简提取公共部分。
{
function creatIndexHandle(dir, arr, item) {
let LEN = arr.length;
let index = dir > 0 ? 0 : LEN - 1;
for (; index >= 0 && index < LEN; index += dir) {
if (arr[index] === item) {
return index
}
}
return -1
}
function arrIndexOfHandle(arr, item) {
return creatIndexHandle(1, arr, item)
}
var arr1 = ['gao', 'bing', 1, 3, 23, 'gao'];
console.log(arrIndexOfHandle(arr1, 'gao')) // 0
console.log(arrIndexOfHandle(arr1, 3)) // 3
console.log(arrIndexOfHandle(arr1, 33)) // -1
function arrLastIndexOfHandle(arr, item) {
return creatIndexHandle(-1, arr, item)
}
var arr = ['gao', 'bing', 1, 3, 23, 'gao', 3];
console.log('gao:' + arrLastIndexOfHandle(arr2, 'gao')) // 5
console.log('3:' + arrLastIndexOfHandle(arr2, 3)) // 6
console.log('33:' + arrLastIndexOfHandle(arr2, 33)) // -1
}
数组转化为字符串
join()
返回一个包含数组所有元素的字符串,各元素之间用逗号分隔开
{
function arrJoinHandle(arr, str) {
let index = -1;
let LEN = arr.length;
let arrStr = '';
if (str == undefined) str = ',' // join 方法接受一个参数的时候,默认通过逗号来进行连接,在这里进行特殊处理
for (var i = 0; i < LEN; i++) {
arrStr += arr[i] + str;
}
return arrStr
}
let arr = ['gao', 'bing', 1, 3, 23, 'gao', 3, 0, '', ' '];
console.log(arrJoinHandle(arr)) // gao,bing,1,3,23,gao,3,0,, ,
console.log(arrJoinHandle(arr, '')) //
VM122393:16 gaobing1323gao30
console.log(arrJoinHandle(arr, '|')) // gao|bing|1|3|23|gao|3|0|| |
}
toString()
toString方法通json方法类似,返回一个包含数组所有元素的字符串,各元素之间用逗号分割开。但是toString不接收第二个参数,当传第二个参数的时候,toString方法默认不处理。
{
function arrToStringHandle(arr) {
let index = -1;
let LEN = arr.length;
let arrStr = '';
for (var i = 0; i < LEN; i++) {
arrStr += arr[i] + ',';
}
return arrStr
}
let arr = ['gao', 'bing', 1, 3, 23, 'gao', 3, 0, '', ' '];
console.log(arrToStringHandle(arr)) // gao,bing,1,3,23,gao,3,0,, ,
console.log(arrToStringHandle(arr, '')) // gao,bing,1,3,23,gao,3,0,, ,
console.log(arrToStringHandle(arr, '|')) // gao,bing,1,3,23,gao,3,0,, ,
}
创建新数组
concat()
合并数组:发起者是一个数组,参数是另外一个数组,作为参数的数组;不改变原数组;
{
function arrContatHandle(arrFirst, arrSecond) {
let arrFirstLEN = arrFirst.length;
for (var i = 0; i < arrSecond.length; i++) {
arrFirst[arrFirstLEN] = arrSecond[i]; // 在插入数据的时候 不能使用push方法,这样我就需要每次插入的时候都得确认插入的位置,每次循环更新插入的位置
arrFirstLEN++;
}
return arrFirst
}
let arr1 = ['gao', 'bing', 1, 3];
let arr2 = [23, 'gao', 3, 0, '', ' '];
let arr3 = ['23', 'bing', ' '];
console.log(arrContatHandle(arr1, arr2)) // ["gao", "bing", 1, 3, 23, "gao", 3, 0, "", " "]
console.log(arrContatHandle(arr3, arr2)) // ["23", "bing", " ", 23, "gao", 3, 0, "", " "]
}
* splice()
会改变原数组,返回一个新数组;接受多个参数,第一个截取的开始索引,第二个是截取的长度,第三、四是要插入的元素。
{
function arrSpliceHandle() {
let args = arguments
let arr = args[0] ? args[0] : [] // 原数组
let startIndex = args[1] ? args[1] : 0 // 截取起始位置
let deleteNum = args[2] ? args[2] : 0 // 要删除元素的个数
let arrLEN = arr.length;
// splice 只有一个参数的时,代表从该起始位置到数组的最后一个元素,返回截取到的数组,会更改原数组
if (args.length == 2) {
if (startIndex < arrLEN) {
arr.length = startIndex
}
return arr
}
// splice 两个参数时,代表从该起始位置开始截取,截取固定的几位,返回截取到的数组,这里需要考虑开始截取的位置的临界值,和要截取个数的临界值
if (args.length == 3) {
if (startIndex < arrLEN && startIndex + deleteNum >= arrLEN) {
arr.length = startIndex
return arr
} else if (startIndex < arrLEN && startIndex + deleteNum < arrLEN) {
let newArr = []
let newArrIndex = 0;
for (var i = 0; i < arrLEN; i++) {
if (i < startIndex) {
newArr[newArrIndex] = arr[i]
newArrIndex++
}
if (i > startIndex + deleteNum - 1) {
newArr[newArrIndex] = arr[i]
newArrIndex++
}
}
return newArr
}
}
// splice 三个参数时,代表从该起始位置开始截取,截取几位,再添加几位元素;这里除了需要考虑开始截取的位置的临界值,和要截取个数的临界值,还需要考虑插入的元素起始位置,和结束位置,以及后面的元素需要向后移动。
if (args.length > 3) {
if (startIndex < arrLEN && startIndex + deleteNum >= arrLEN) {
arr.length = startIndex
return concatArrHandle(arr)
} else if (startIndex < arrLEN && startIndex + deleteNum < arrLEN) {
let newArr = []
let newArrIndex = 0;
for (var i = 0; i < arrLEN; i++) {
if (i < startIndex) {
newArr[newArrIndex] = arr[i]
newArrIndex++
}
if (i > startIndex + deleteNum - 1) {
newArr[newArrIndex] = arr[i]
newArrIndex++
}
}
return concatArrHandle(newArr)
}
}
function concatArrHandle(tempArr) {
let tempArrLEN = tempArr.length
for (let j = 3; j < args.length; j++) {
tempArr[tempArrLEN] = args[j]
tempArrLEN++
}
return tempArr
}
return arr
}
let arr1 = ['gao', 'bing', 1, 3]
let arr2 = ['gao', 'bing', 1, 3]
let arr3 = ['gao', 'bing', 1, 3]
let arr4 = ['gao', 'bing', 1, 3]
let arr5 = ['gao', 'bing', 1, 3]
console.log(arrSpliceHandle(arr1, 0)) // []
console.log(arrSpliceHandle(arr2, 0, 6)) // []
console.log(arrSpliceHandle(arr3, 2, 6)) // ["gao", "bing"]
console.log(arrSpliceHandle(arr4, 1, 2)) // ["gao", 3]
console.log(arrSpliceHandle(arr5, 1, 2, 'yan', 'gaoxiaohei', 'gaoheihei')) // ["gao", 3, "yan", "gaoxiaohei",
}
为数组添加元素
push() 将一个元素(多个元素)添加到数组末尾
{
function arrPushHandle() {
let args = arguments; // 接收参数
let argsLEN = arguments.length // 参数的长度
let arr = arguments[0] // 要加入元素的数组
let arrLEN = arr.length // 要加入元素的数组的长度
for (var i = 1; i < argsLEN; i++) {
arr[arrLEN] = args[i]
arrLEN++
}
return arr
}
let arr1 = ['gao', 'bing', 1, 3];
let arr2 = ['gao', 'bing', 1, 3];
let arr3 = ['gao', 'bing', 1, 3];
console.log(arrPushHandle(arr1, 2)) // ["gao", "bing", 1, 3, 2]
console.log(arrPushHandle(arr2, 'gaoheihei')) // ["gao", "bing", 1, 3, "gaoheihei"]
console.log(arrPushHandle(arr3, 2, 'gaoheihei')) // ["gao", "bing", 1, 3, 2, "gaoheihei"]
}
unshift() 将一个元素(多个元素)添加数组的开头
{
function arrUnshiftHandle() {
let args = arguments; // 接收参数
let argsLEN = args.length // 参数的长度
let arr = args[0] // 要加入元素的数组
let arrLEN = arr.length // 要加入元素的数组的长度
// 元素后移
for (var i = arrLEN; i >= 0; i--) {
arr[i + argsLEN - 2] = arr[i - 1]
}
// 插入新元素
let addIndex = 0;
for(let j = 1; j < argsLEN; j++ ) {
arr[addIndex] = args[j]
addIndex++
}
return arr
}
let arr1 = ['gao', 'bing', 1, 3];
let arr2 = ['gao', 'bing', 1, 3];
let arr3 = ['gao', 'bing', 1, 3];
console.log(arrUnshiftHandle(arr1, 2)) // [2, "gao", "bing", 1, 3]
console.log(arrUnshiftHandle(arr2, 'gaoheihei')) // ["gaoheihei", "gao", "bing", 1, 3]
console.log(arrUnshiftHandle(arr3, 2, 'gaoheihei')) // [2, "gaoheihei", "gao", "bing", 1, 3]
}
新的数组添加进来后,需要将后面的每个元素都相应地向后移一个位置
为数组删除元素
pop() 将一个元素从数组末尾删除
不接受传参
{
function arrPopHandle(arr) {
if (arr.length > 0) { // 空数组,数组长度不减1
arr.length = arr.length - 1
}
return arr
}
let arr1 = ['gao', 'bing', 1, 3]
let arr2 = ['gao', 'bing', 1]
let arr3 = []
console.log(arrPopHandle(arr1)) // ["gao", "bing", 1]
console.log(arrPopHandle(arr2)) // ["gao", "bing"]
console.log(arrPopHandle(arr3)) // []
}
shift() 将一个元素从数组的开头删除
{
function arrShiftHandle(arr) {
let LEN = arr.length;
for (var i = 0; i < LEN; i++) {
arr[i] = arr[i+1]
}
if (LEN > 1) { // 处理空数组 极限情况,若不是空数组,数组长度-1
arr.length = arr.length - 1
}
return arr
}
let arr1 = ['gao', 'bing', 1, 3]
let arr2 = ['gao', 'bing', 1]
let arr3 = []
console.log(arrShiftHandle(arr1)) // ["bing", 1, 3]
console.log(arrShiftHandle(arr2)) // ["bing", 1]
console.log(arrShiftHandle(arr3)) // []
}
头部删除了元素,并没有改变数组的长度,需要重置数组的长度
为数组排序
reverse()
该方法将数组中元素的顺序进行翻转
{
function arrReverseHandle(arr) {
let LEN = arr.length
let newArr = []
for(var i = 0; i < arr.length; i++) {
newArr[LEN - 1] = arr[i]
LEN--
}
return newArr
}
let arr1 = ['gao', 'bing', 1, 3]
let arr2 = ['gao', 'bing', 1]
let arr3 = []
console.log(arrReverseHandle(arr1)) // [3, 1, "bing", "gao"]
console.log(arrReverseHandle(arr2)) // [1, "bing", "gao"]
console.log(arrReverseHandle(arr3)) // []
}
sort()
按照字典顺序对元素排序