DAY10 手写js系列(七)
2022/4/5
# DAY10 手写js系列(七)
# 30. 数组some方法
Array.prototype.my_some = function (callback) {
for (let i = 0; i < this.length; i++) {
if (callback(this[i], i, this)) {
return true
}
}
return false
}
# 31. 数组reduce方法
Array.prototype.my_reduce = function (callback, ...args) {
let startIndex = 0
let pre
if (args.length) {
pre = args[0]
} else {
pre = this[0]
startIndex = 1
}
for (let i = startIndex; i < this.length; i++) {
pre = callback(pre, this[i], i, this)
}
return pre
}
# 32. 数组findIndex方法
Array.prototype.my_findIndex = function (callback) {
for (let i = 0; i < this.length; i++){
if (callback(this[i], i, this)) return i
}
return -1
}
# 33. 数组find方法
Array.prototype.my_find = function (callback) {
for (let i = 0; i < this.length; i++) {
if (callback(this[i], i, this)) return this[i]
}
return undefined
}
# 34. 数组fill方法
用于填充数组,左闭右开,end默认为length
Array.prototype.my_fill = function (value, start = 0, end = this.length) {
for (let i = start; i < end; i++) {
this[i] = value
}
return this
}
# 35. 数组includes方法
注意NaN在比较时,NaN永远不等于NaN
Array.prototype.my_includes = function (value, start) {
if (start < 0) start = this.length - start
const isNaN = Number.isNaN(value)
for (let i = start; i < this.length; i++) {
if (this[i] === value || (isNaN && Number.isNaN(this[i]))) return true
}
return false
}
# 36. 数组join方法
Array.prototype.my_join = function (sep = ',') {
let str = ''
for (let i = 0; i < this.length; i++){
str += i === 0 ? `${this[i]}` : `${sep}${this[i]}`
}
return str
}
# 37. 数组flat方法
Array.prototype.my_flat = function (level = Infinity) {
let res = this
while (res.some((item) => Array.isArray(item))) {
if (level <= 0) break
res = [].concat(...res)
level--
}
return res
}
# 38. 数组splice方法
参数校验
- startIndex 为非法值,直接返回空数组
- startIndex为负数,startIndex += length
- startIndex超出索引
- args.length === 0 : 直接返回空数组
- args.length !== 0: 插入到末尾
- delnum > length - startIndex : delnum = length - startIndex
- delnum < 0 或 非法值 , delnum = 0
- delnum > args.length , 先替换,然后把剩下的删除
- delnum < args.length , 先替换删除的长度,然后再插入剩下的元素
插入函数
function insert(arr, start, items, itemsStartIndex) {
let insLen = items.length - itemsStartIndex
// i指向原来数组末尾
let i = arr.length - 1
// 数组扩容
arr.length += insLen
// j指向当前数组末尾
let j = arr.length - 1
// 元素向后挪
while (i >= start) {
arr[j--] = arr[i--]
}
// 插入元素
for (let i = itemsStartIndex; i < itemsStartIndex + insLen; i++) {
arr[start++] = items[i]
}
}
替换函数
可用于删除
function replace(arr, start, items, itemsStartIndex) {
let delItems = []
if (start > arr.length) start = arr.length
// 替换的数量
let repLen = items.length - itemsStartIndex
// 计算得到删除元素的数量
let count
if (arr === items) {
count = itemsStartIndex - start
} else {
count = items.length
}
let i = start,
j = itemsStartIndex
while (j < items.length) {
if (arr[i] && count !== 0) {
delItems.push(arr[i])
--count
}
arr[i++] = items[j++]
}
return delItems
}
删除函数
function del(arr, start, count) {
if (start < 0 || start >= arr.length) return []
if (count > arr.length) count = arr.length
let delItems = replace(arr, start, arr, start + count)
arr.length -= count
return delItems
}
splice函数
Array.prototype.my_splice = function (startIndex, delnum, ...args) {
// startIndex非法,直接结束
if (typeof startIndex !== 'number' && typeof startIndex !== 'string') return []
// 获取数组长度
let len = this.length
// 处理开始索引,保证索引为正数
if (typeof startIndex === 'string') startIndex = Number(startIndex)
if (startIndex < 0) startIndex += len
// 处理删除数量,保证 0 <= delnum <= len - startIndex
if (typeof delnum === 'string') delnum = Number(delnum)
if (delnum < 0 || typeof delnum !== 'number') delnum = 0
if (delnum > len - startIndex) delnum = len - startIndex
let res = []
if (delnum === args.length) {
res = replace(this, startIndex, args, 0)
} else if (delnum > args.length) {
res = replace(this, startIndex, args, 0)
res.push(...del(this, startIndex + args.length, delnum - args.length))
} else {
let args1 = [...args]
args1.length = delnum
res = replace(this , startIndex , args1 , 0)
insert(this , startIndex + delnum , args , delnum)
}
return res
}