通过函数实现数组方法
通过实现数组方法来让我们对数组方法的认识更加加深一些。
测试函数
我们先创建个函数,让我们更好的看到函数的输入输出等等。
js
// 帮助函数
function logOperation(operationName, array, callback) {
const input = [...array]
const result = callback(array)
console.log({
operation: operationName,
arrayBefore: input,
arrayAfter: array,
mutates: mutatesArray(input, array), // shallow check
result
})
}
function mutatesArray(firstArray, secondArray) {
if (firstArray.length !== secondArray.length) {
return true
}
for (let index = 0; index < firstArray.length; index += 1) {
if (firstArray[index] !== secondArray[index]) {
return true
}
}
return false
}
forEach
- 作用:对数组的每个元素执行一次提供的函数。
实现
js
function forEach(array, callback) {
const length = array.length
for (let index = 0; index < length; index++) {
const value = array[index]
callback(value, index, array)
}
}
测试
js
let arr = [1, 2, 3, 4, 5]
logOperation('forEach', arr, (array) => forEach(array, (value) => value++))
//打印信息
{
operation: 'forEach',//方法名
arrayBefore: [ 1, 2, 3, 4, 5 ],//原数组
arrayAfter: [ 1, 2, 3, 4, 5 ],//新数组
mutates: false,//是否改变了数组
result: undefined//返回值
}
map
- 作用:原数组的每个元素都调用一次 callback 函数,callback 每次执行后的返回值会组成一个新数组。
实现
js
function map(array, callback) {
const result = []
const length = array.length
for (let index = 0; index < length; index++) {
const value = array[index]
result[index] = callback(value, index, array)
}
return result
}
测试
js
let arr=[1,2,3,4,5]
logOperation('map',arr,array=>map(array,value=>value+5))
{
operation: 'map',
arrayBefore: [ 1, 2, 3, 4, 5 ],
arrayAfter: [ 1, 2, 3, 4, 5 ],
mutates: false,
result: [ 6, 7, 8, 9, 10 ]
}
filter
- 作用:过滤掉回调函数返回为 false 的值,然后返回 true 的值保存到新数组中。
实现
js
function filter(array, callback) {
const result = []
const length = array.length
for (let index = 0; index < length; index++) {
const value = array[index]
if (callback(value, index, array)) {
result.push(value)
}
}
return result
}
测试
js
let arr=[1,2,3,4,5]
logOperation('filter',arr,array=>filter(array,value=>value>2))
//打印
{
operation: 'filter',
arrayBefore: [ 1, 2, 3, 4, 5 ],
arrayAfter: [ 1, 2, 3, 4, 5 ],
mutates: false,
result: [ 3, 4, 5 ]
}
reduce
- 作用:接受个函数作为累加器,数组中的每个值开始递减,最终计算为一个值。
实现
js
function reduce(array, callback, initValue) {
const length = array.length
let acc = initValue
let startAtIndex = 0
if (initValue === undefined) {
acc = array[0]
startAtIndex = 0
}
for (let index = startAtIndex; index < length; index++) {
const value = array[index]
acc = callback(acc, value, index, array)
}
return acc
}
测试
js
let arr=[1,2,3,4,5]
logOperation('reduce',arr,array=>reduce(array,(pre,cur)=>pre+cur,0))
//打印
{
operation: 'reduce',
arrayBefore: [ 1, 2, 3, 4, 5 ],
arrayAfter: [ 1, 2, 3, 4, 5 ],
mutates: false,
result: 15
}
findIndex
- 作用:找到数组中给定值的索引
实现
js
function findIndex(array, callback) {
const length = array.length
for (let index = 0; index < length; index++) {
const value = array[index]
if (callback(value, index, array)) {
return index
}
}
return -1
}
测试
js
let arr = [1, 2, 3, 4, 5]
logOperation('findIndex', arr, (array) =>
findIndex(array, (number) => number === 3)
)
//打印
{
operation: 'findIndex',
arrayBefore: [ 1, 2, 3, 4, 5 ],
arrayAfter: [ 1, 2, 3, 4, 5 ],
mutates: false,
result: 2
}
find
- 作用:返回的是实际的值,而不是索引
实现
js
function find(array, callback) {
const length = array.length
for (let index = 0; index < length; index++) {
const value = array[index]
if (callback(value, index, array)) {
return array[index]
}
}
return undefined
}
测试
js
let arr = [1, 2, 3, 4, 5]
logOperation('find', arr, (array) => find(array, (number) => number === 3))
//打印
{
operation: 'find',
arrayBefore: [ 1, 2, 3, 4, 5 ],
arrayAfter: [ 1, 2, 3, 4, 5 ],
mutates: false,
result: 3
}
indexOf
- 作用:获取给定索引值的另一个方法。
js
function indexOf(array, searchValue, formIndex) {
const length = array.length
let start = formIndex || 0
if (start >= length || length === 0) {
return -1
}
start = start >= 0 ? start : length - Math.abs(start)
for (let index = start; index < length; index++) {
const value = array[index]
if (value === searchValue) {
return index
}
}
return -1
}
测试
js
let arr = [1, 2, 3, 4, 5]
logOperation('indexOf', arr, (array) => indexOf(array, 3))
//打印
{
operation: 'indexOf',
arrayBefore: [ 1, 2, 3, 4, 5 ],
arrayAfter: [ 1, 2, 3, 4, 5 ],
mutates: false,
result: 2
}
lastIndexOf
- 作用:返回指定元素在数组中的最后一个的索引
实现
js
function lastIndexOf(array, searchValue) {
const length = array.length
for (let index = length - 1; index > -1; index--) {
const value = array[index]
if (value === searchValue) {
return index
}
}
return -1
}
测试
js
let arr = [1, 2, 3, 4, 5]
logOperation('lastIndexOf', arr, (array) => lastIndexOf(array, 3))
//打印
{
operation: 'lastIndexOf',
arrayBefore: [ 1, 2, 3, 4, 5 ],
arrayAfter: [ 1, 2, 3, 4, 5 ],
mutates: false,
result: 2
}
every
- 作用:测试一个数组中的所有元素都能通过某个指定函数的测试,返回一个布尔值。
实现
js
function every(array, callback) {
const length = array.length
for (let index = 0; index < length; index++) {
const value = array[index]
if (!callback(value, index, array)) {
return false
}
}
return true
}
测试
js
let arr = [1, 2, 3, 4, 5]
logOperation('every', arr, (array) =>
every(array, (number) => Number.isInteger(number))
)
//打印
{
operation: 'every',
arrayBefore: [ 1, 2, 3, 4, 5 ],
arrayAfter: [ 1, 2, 3, 4, 5 ],
mutates: false,
result: true
}
some
- 作用:some 的作用与 every 相反,只要其中一个为 true 就会返回 true。
实现
js
function some(array, callback) {
const length = array.length
for (let index = 0; index < length; index++) {
const value = array[index]
if (callback(value, index, array)) {
return true
}
}
return false
}
测试
js
let arr = [1, 2, 3, 4, 5]
logOperation('some', arr, (array) => some(array, (number) => number === 5))
//打印
{
operation: 'some',
arrayBefore: [ 1, 2, 3, 4, 5 ],
arrayAfter: [ 1, 2, 3, 4, 5 ],
mutates: false,
result: true
}
includes
- 作用:提供一个参数来比较数组中的元素,如果数组中含有则返回 true。
实现
js
function inclues(array, findValue) {
const length = array.length
for (let index = 0; index < length; index++) {
const value = array[index]
if (value === findValue) {
return true
}
}
return false
}
测试
js
let arr = [1, 2, 3, 4, 5]
logOperation('includes', arr, (array) => inclues(array, 5))
{
operation: 'includes',
arrayBefore: [ 1, 2, 3, 4, 5 ],
arrayAfter: [ 1, 2, 3, 4, 5 ],
mutates: false,
result: true
}
concat
- 作用:用于合并两个或者多个的数组,此方法不会更变原数组,而是返回一个新数组。
实现
js
function concat(array, ...values) {
const result = [...array]
const length = values.length
for (let index = 0; index < length; index++) {
const value = values[index]
if (Array.isArray(value)) {
result.push(...value)
} else {
result.push(value)
}
}
return result
}
测试
js
let arr=[1,2,3,4,5]
logOperation('concat',arr,array=>concat(array,1,2,[3,4]))
{
operation: 'concat',
arrayBefore: [ 1, 2, 3, 4, 5 ],
arrayAfter: [ 1, 2, 3, 4, 5 ],
mutates: false,
result: [
1, 2, 3, 4, 5,
1, 2, 3, 4
]
}
join
- 作用:把数组中的所有元素放入一个字符串,元素是通过指定的分隔符进行分割。
实现
js
function join(array, joinWith) {
let length = array.length
let str = ''
let i = 0
if (!Array.isArray(array)) {
return console.log('不是数组')
}
if (length === 0) {
return ''
}
if (length === 1) {
return `${array[0]}`
}
str = array[0]
i = 1
for (let index = i; index < length; index++) {
const value = array[index]
str += `${joinWith}${value}`
}
return str
}
测试
js
let arr = [1, 2, 3, 4, 5]
logOperation('join', arr, (array) => join(array, ','))
{
operation: 'join',
arrayBefore: [ 1, 2, 3, 4, 5 ],
arrayAfter: [ 1, 2, 3, 4, 5 ],
mutates: false,
result: '1,2,3,4,5'
}
reverse
- 作用:将数组中的元素的位置颠倒,并返回该数组,该方法会改变原数组。
实现
js
function reverse(array) {
const result = []
const lastIndex = array.length - 1
for (let index = lastIndex; index > -1; index--) {
const value = array[index]
result[lastIndex - index] = value
}
return result
}
测试
js
let arr = [1, 2, 3, 4, 5]
logOperation('reverse', arr, (array) => reverse(array))
{
operation: 'reverse',
arrayBefore: [ 1, 2, 3, 4, 5 ],
arrayAfter: [ 1, 2, 3, 4, 5 ],
mutates: false,
result: [ 5, 4, 3, 2, 1 ]
}
shift
- 作用:从数组中删除第一个元素,并返回该元素的值,此方法改变数组的长度。
实现
js
function shift(array) {
const length = array.length
const firstValue = array[0]
for (let index = 1; index < length; index++) {
const value = array[index]
array[index - 1] = value
}
array.length = length - 1
return firstValue
}
测试
js
let arr = [1, 2, 3, 4, 5]
logOperation('shift', arr, (array) => shift(array))
{
operation: 'shift',
arrayBefore: [ 1, 2, 3, 4, 5 ],
arrayAfter: [ 2, 3, 4, 5 ],
mutates: true,
result: 1
}```
## unshift
- 作用:将一个元素或多个元素添加到数组的开头,并返回该数组的新长度。
**实现**
```js
function unshift(array, ...values) {
const mergeArr = concat(values, ...array)
const length = mergeArr.length
for (let index = 0; index < length; index++) {
const value = mergeArr[index]
array[index] = value
array[index] = value
}
return array.length
}
测试
js
let arr = [1, 2, 3, 4, 5]
logOperation('unshift', arr, (array) => unshift(array))
{
operation: 'unshift',
arrayBefore: [ 1, 2, 3, 4, 5 ],
arrayAfter: [ 1, 2, 3, 4, 5 ],
mutates: false,
result: 5
}
slice
- 作用:返回一个截取出来的新数组。
实现
js
function slice(array, startIndex = 0, endIndex = array.length) {
const result = []
for (let index = startIndex; index < endIndex; index++) {
const value = array[index]
if (index < array.length) {
result.push(value)
}
}
return result
}
测试
js
let arr = [1, 2, 3, 4, 5]
logOperation('slice', arr, (array) => slice(array, 1, 3))
{
operation: 'slice',
arrayBefore: [ 1, 2, 3, 4, 5 ],
arrayAfter: [ 1, 2, 3, 4, 5 ],
mutates: false,
result: [ 2, 3 ]
}
splice
- 作用:方法通过删除或替换现有元素来修改数组。
实现
js
function splice(array, insertAtIndex, removeNumberOfElements, ...values) {
const firstPart = slice(array, 0, insertAtIndex)
const secondPart = slice(array, insertAtIndex + removeNumberOfElements)
const removedElements = slice(array, insertAtIndex, insertAtIndex + removeNumberOfElements)
const joinedParts = firstPart.concat(values, secondPart)
const joinedPartsLength = joinedParts.length
for (let index = 0; index < joinedPartsLength; index++) {
array[index] = joinedParts[index]
array.length = joinedPartsLength
return removeNumberOfElements
}
}
测试
js
let arr=[1,2,3,4,5]
logOperation('splice',arr,array=>splice(array,1,3))
{
operation: 'splice',
arrayBefore: [ 1, 2, 3, 4, 5 ],
arrayAfter: [ 1, 2 ],
mutates: true,
result: 3
}
pop
- 作用:从数组中删除最后一个元素,并返回该元素的值。
实现
js
function pop(array) {
const value = array[array.length - 1]
array.length = array.length - 1
return value
}
测试
js
let arr = [1, 2, 3, 4, 5]
logOperation('pop', arr, (array) => pop(array))
{
operation: 'pop',
arrayBefore: [ 1, 2, 3, 4, 5 ],
arrayAfter: [ 1, 2, 3, 4 ],
mutates: true,
result: 5
}
push
- 作用:将一个或多个元素添加到数组的末尾,并返回该数组的新长度。
实现
js
function push(array, ...values) {
const { length: arrayLength } = array
const { length: valuesLength } = values
for (let index = 0; index < valuesLength; index += 1) {
array[arrayLength + index] = values[index]
}
return array.length
}
测试
js
let arr = [1, 2, 3, 4, 5]
logOperation('push', arr, (array) => push(array, 6, 7))
{
operation: 'push',
arrayBefore: [ 1, 2, 3, 4, 5 ],
arrayAfter: [
1, 2, 3, 4,
5, 6, 7
],
mutates: true,
result: 7
}
fill
- 作用:用一个占位符来填充一个数组。
实现
js
function fill(array, value, startIndex = 0, endIndex = array.length) {
for (let index = startIndex; index < array.length; index++) {
array[index] = value
}
return array
}
测试
js
let arr = new Array(5)
logOperation('fill', arr, (array) => fill(array, 1))
{
operation: 'fill',
arrayBefore: [ undefined, undefined, undefined, undefined, undefined ],
arrayAfter: [ 1, 1, 1, 1, 1 ],
mutates: true,
result: [ 1, 1, 1, 1, 1 ]
}