あるインタビュアーから、「js 配列プロトタイプのほとんどのメソッドを実装するために for または while を使用できますか?」と尋ねられました。当時はとても戸惑いました。自分で試したことはなく、できるかどうかもわかりませんでしたが、それほど難しいとは思わなかったので、「はい!」と言いました。 很遗憾,后面他也祝我早日找到更匹配的工作了~
その後、自分で実装しようとしましたが、その過程で、いくつかの方法は比較的簡単でした。不足がある場合は、いくつかの兄貴がアドバイスをくれることを願っています。私が達成できない方法がいくつかあります:などsort
. reduce
しかし、それらのほとんどを達成することもできます。一部のメソッドについては、実装のアイデアを書きました可能写得不清楚,
が、アイデアを実装するメソッドを書いていないため、説明できません。コードを見て理解するだけ!! !
で
公式の説明:at()
メソッドは整数値を受け取り、そのインデックスの項目を返します。正と負の数を許可します。負の整数は、配列の最後の項目から数えます。大まかな意味: インデックスを指定すると、現在のインデックスの値を返します。
アイデア:
- 渡されたインデックスが 0 より大きい場合、現在のインデックス値が直接返されます。
- 渡されたインデックスが 0 未満の場合、最後から 2 番目の
i
要素、式: this.length + iを返します。- 渡されたインデックスが 0 の場合、最初の要素が直接返されます。
const sect = ['少林派', '武当派', '逍遥派', '峨眉派', '华山派', '日月神教', '古墓派', '全真教', '丐帮', '明教']
Array.prototype.myAt = function(i) {
let index = parseInt(i)
if (index > 0) {
return this[index]
} else if (index < 0) {
return this[this.length + index]
} else {
return this[0]
}
}
const value = sect.myAt(3)
const value1 = sect.myAt(-1)
console.log('原数组:', sect)
console.log(value)
console.log(value1)
連結
公式説明:concat()
このメソッドは、2 つ以上の配列をマージするために使用されます。このメソッドは既存の配列を変更しませんが、新しい配列を返します。
アイデア:
最初に空の配列を用意し、次に元の配列をトラバースし、用意した空の配列にすべての値を入れます。これは元の配列とまったく同じです。
- パラメータが渡されない場合 (arguments.length < 1)、この配列を直接返します
- パラメーターが渡されない場合 (arguments.length >= 1)、実際のパラメーターがトラバースされます。
- 現在の実パラメータが配列でない場合、事前に準備された配列に直接挿入されます。
- 現在の実パラメータが配列の場合、配列をトラバースして、前に準備した配列に 1 つずつ挿入します。
const array1 = ['倚天屠龙记', '射雕英雄传'];
const array2 = ['笑傲江湖', '神雕侠侣'];
Array.prototype.myConcat = function() {
let temp = []
for (let u = 0; u < this.length; u++) {
temp.push(this[u])
}
// 当不传参数时
if (arguments.length < 1) {
return temp;
}
// 如果有参数,遍历实参
for (let i = 0; i < arguments.length; i++) {
// 当前实参
let currentArg = arguments[i]
// 当实参不是数组类型
if (Object.prototype.toString.call(currentArg) !== '[object Array]') {
temp.push(currentArg)
} else {
for (let j = 0; j < currentArg.length; j++) {
temp.push(currentArg[j])
}
}
}
return temp
}
let array3 = array1.myConcat()
let array4 = array1.myConcat(array2)
let array5 = array1.myConcat(array2, '天龙八部')
console.log(array3)
console.log(array4)
console.log(array4)
毎日
公式の説明:every()
このメソッドは、配列内のすべての要素が指定された関数のテストに合格できるかどうかをテストします。ブール値を返します。
アイデア:
渡されたものが関数かどうかをまず判断し、関数でない場合はエラーをスローします。メソッドの場合は、この配列をトラバースし、コールバック関数を実行して、現在トラバースされている値、インデックス、および配列全体を渡します。コールバック関数が
false
直接 を返した場合return false
、配列全体がトラバースされた場合return true
const array1 = [1, 30, 39, 29, 10, 13]
Array.prototype.myEvery = function(fun) {
let isFunction = Object.prototype.toString.call(fun) === '[object Function]'
if (!isFunction) {
throw new Error('请传入一个方法。')
}
// 遍历当前数组,执行回调函数并传入当前遍历的值
for (let i = 0; i < this.length; i++) {
let flag = fun(this[i], i, this)
if (!flag) {
return false
}
}
return true
}
console.log(array1.myEvery(item => item < 50))
console.log(array1.myEvery(item => item < 20))
塗りつぶし
公式の説明:fill()
このメソッドは、配列内の開始インデックスから終了インデックスまでのすべての要素を固定値で埋めます。終了インデックスは含まれません。
アイデア:
空の配列を準備し、この配列をトラバースします。
- パラメータを渡すとき、このパラメータを空の配列に挿入し、
- 2 つのパラメータを渡す場合、
- トラバースされた値が 2 番目のパラメーターより小さい場合は、配列の値を準備したばかりの配列に挿入します。
- トラバースされたインデックスが 2 番目のパラメーター以上の場合、準備した配列に最初のパラメーターを挿入します。
- 3 つのパラメーターを渡す場合も同じです。! !
const array1 = [1, 2, 3, 4];
Array.prototype.myFill = function() {
let temp = []
let leng = arguments.length
for (let i = 0; i < this.length; i++) {
if (leng === 1) {
temp.push(arguments[0])
} else if (leng === 2) {
let start = parseInt(arguments[1])
if(i < start) {
temp.push(this[i])
} else {
temp.push(arguments[0])
}
} else {
let start = parseInt(arguments[1])
let end = parseInt(arguments[2])
if(i < start || i >= end) {
temp.push(this[i])
} else {
temp.push(arguments[0])
}
}
}
return temp
}
const array2 = array1.myFill(8)
const array3 = array1.myFill(8, 1)
const array4 = array1.myFill(8, 1, 3)
console.log(array2)
console.log(array3)
console.log(array4)
フィルター
公式の説明:filter()
このメソッドは、指定された配列の一部の浅いコピーを作成します。これには、指定された関数によって実装されたテストに合格したすべての要素が含まれます。大まかな意味: 配列から必要なデータを除外します。
アイデア:
まず、パラメータが関数ではなく関数であるかどうかを判断し、エラーをスローします! 関数の場合は、この配列をトラバースしてコールバック関数を実行し、コールバック関数が を返したら、
true
準備した空の配列に現在の値を挿入し、最後にこの配列を返します。
const sect = ['少林派', '武当派', '逍遥派', '峨眉派', '华山派', '日月神教', '古墓派', '全真教', '丐帮', '明教']
Array.prototype.myFilter = function(fun) {
let isFunction = Object.prototype.toString.call(fun) === '[object Function]'
if (!isFunction) {
throw new Error('请传入一个方法。')
}
let temp = []
for (let i = 0; i < this.length; i++) {
let flag = fun(this[i], i, this)
if (flag) {
temp.push(this[i])
}
}
return temp
}
let newSect = sect.myFilter(item => item.length === 2)
console.log(newSect)
探す
公式の説明:find()
このメソッドは、提供されたテスト関数を満たす配列内の最初の要素の値を返します。それ以外の場合は戻りますundefined
。
アイデア:
まず、パラメータが関数ではなく関数であるかどうかを判断し、エラーをスローします! 関数の場合は、この配列をトラバースし、コールバック関数を実行します。コールバック関数が を返す場合は
true
、return
その中の現在の値をトラバースします。トラバーサルが終了し、コールバック関数が を返さない場合true
、return undefined
const array1 = [5, 12, 8, 130, 44];
Array.prototype.myFind = function(fun) {
let isFunction = Object.prototype.toString.call(fun) === '[object Function]'
if (!isFunction) {
throw new Error('请传入一个方法。')
}
for (let i = 0; i < this.length; i++) {
let target = fun(this[i], i, this)
if (target) {
return this[i]
}
}
return undefined
}
console.log(array1.myFind(item => item > 20));
console.log(array1.myFind(item => item > 200));
検索ラスト
公式の説明:findLast()
このメソッドは、提供されたテスト関数の条件を満たす配列内の最後の要素の値を返します。対応する要素が見つからない場合に返しますundefined
。
アイデア:
原則は同じ
find
ですが、配列をループするときは右から左にループします。
const array1 = [5, 12, 8, 130, 44]
Array.prototype.myFindLast = function(fun) {
let isFunction = Object.prototype.toString.call(fun) === '[object Function]'
if (!isFunction) {
throw new Error('请传入一个方法。')
}
for (let i = this.length - 1; i >= 0; i--) {
let target = fun(this[i], i, this)
if (target) {
return this[i]
}
}
return undefined
}
console.log(array1.myFindLast(item => item > 20))
console.log(array1.myFindLast(item => item > 200))
検索インデックス
公式の説明:findIndex()
このメソッドは、提供されたテスト関数を満たす配列内の最初の要素のインデックスを返します。対応する要素が見つからない場合は -1 を返します。
アイデア:
まず、パラメータが関数ではなく関数であるかどうかを判断し、エラーをスローします! 関数の場合は、この配列をトラバースし、コールバック関数を実行します。コールバック関数が を返す場合は
true
、return
配列内の現在のインデックスをトラバースします。トラバーサルが終了し、コールバック関数が を返さない場合true
、return -1
const array1 = [5, 12, 8, 130, 44]
Array.prototype.myFindIndex = function(fun) {
let isFunction = Object.prototype.toString.call(fun) === '[object Function]'
if (!isFunction) {
throw new Error('请传入一个方法。')
}
for (let i = 0; i < this.length; i++) {
let target = fun(this[i], i, this)
if (target) {
return i
}
}
return -1
}
console.log(array1.myFindIndex(item => item > 10));
console.log(array1.myFindIndex(item => item > 1000));
検索最後のインデックス
公式の説明:findLastIndex()
このメソッドは、提供されたテスト関数の条件を満たす配列内の最後の要素のインデックスを返します。対応する要素が見つからない場合は、-1 が返されます。
アイデア:
原則は同じ
findIndex
ですが、配列をループするときは右から左にループします。
const array1 = [5, 12, 8, 130, 44]
Array.prototype.myFindLastIndex = function(fun) {
let isFunction = Object.prototype.toString.call(fun) === '[object Function]'
if (!isFunction) {
throw new Error('请传入一个方法。')
}
for (let i = this.length - 1; i >= 0; i--) {
let target = fun(this[i], i, this)
if (target) {
return i
}
}
return -1
}
console.log(array1.myFindLastIndex(item => item > 10))
console.log(array1.myFindLastIndex(item => item > 1000))
forEach
公式の説明:forEach()
メソッドは、配列の要素ごとに指定された関数を 1 回実行します。
const sect = ['少林派', '武当派', '逍遥派', '峨眉派', '华山派', '日月神教', '古墓派', '全真教', '丐帮', '明教']
Array.prototype.myForEach = function(fun) {
let isFunction = Object.prototype.toString.call(fun) === '[object Function]'
if (!isFunction) {
throw new Error('请传入一个方法。')
}
for (let i = 0; i < this.length; i++) {
fun(this[i], i, this)
}
}
sect.myForEach((item, i, arr) => console.log(item, i, arr))
含む
公式説明:forEach()
メソッドは、配列に指定された値が含まれているかどうかを状況に応じて判断するために使用され、含まれている場合は戻りtrue
、含まれていない場合は戻りますfalse
。
アイデア:
配列を 1 つずつトラバースして、パラメータとトラバーサルの現在の値が等しいかどうかを判断します
return true
。return false
const sect = ['少林派', '武当派', '逍遥派', '峨眉派', '华山派', '日月神教', '古墓派', '全真教', '丐帮', '明教']
Array.prototype.myIncludes = function(value) {
if (!value) {
return false
}
for (let i = 0; i < this.length; i++) {
if (value === this[i]) {
return true
}
}
return false
}
console.log(sect.myIncludes('明教'))
console.log(sect.myIncludes('伊斯兰'))
の指標
公式の説明:indexOf()
このメソッドは、指定された要素が配列内で見つかる最初のインデックスを返します。存在しない場合は -1 を返します。
const beasts = ['ant', 'bison', 'camel', 'duck', 'bison'];
Array.prototype.myIndexOf = function(target, index) {
if (!target) {
return -1
}
index = parseInt(index)
let i = 0;
if (index && index > 0 && index <= this.length) {
i = index
}
if (index && index < 0 && index >= -(this.length)) {
i = this.length + index
}
for (i; i < this.length; i++) {
if (target === this[i]) {
return i
}
}
return -1
}
console.log(beasts.myIndexOf('bison'))
console.log(beasts.myIndexOf('bison', 4))
lastIndexOf
公式の説明:lastIndexOf()
このメソッドは、配列内の指定された要素 (つまり、有効な JavaScript 値または変数) の最後のインデックスを返すか、存在しない場合は -1 を返します。fromIndexから始めて、配列の後ろから前を見てください
const beasts = ['ant', 'bison', 'camel', 'duck', 'bison'];
Array.prototype.myLastIndexOf = function(target, index) {
if (!target) {
return -1
}
index = parseInt(index)
let i = this.length - 1;
if (index && index > 0 && index <= this.length) {
i = index
}
if (index && index < 0 && index >= -(this.length)) {
i = this.length + index
}
for (i; i >= 0; i--) {
if (target === this[i]) {
return i
}
}
return -1
}
console.log(beasts.myLastIndexOf('bison'))
console.log(beasts.myLastIndexOf('bison', 4))
加入
公式の説明:join()
このメソッドは、配列 (または配列のようなオブジェクト) のすべての要素を文字列に連結し、その文字列を返します。配列に項目が 1 つしかない場合、その項目はセパレーターなしで返されます。
const elements = ['Fire', 'Air', 'Water']
Array.prototype.myJoin = function(target) {
let str = ''
for (let i = 0; i < this.length; i++) {
if (!target) {
str += this[i] + ','
} else {
str += this[i] + target
}
}
return str.slice(0, str.length - 1)
}
console.log(elements.myJoin())
console.log(elements.myJoin('-'))
console.log([].myJoin()) // ''
地図
公式の説明:map()
このメソッドは、元の配列の各要素に対して提供された関数を 1 回呼び出した後、戻り値で構成される新しい配列を作成します。
アイデア:
まず、パラメータが関数ではなく関数であるかどうかを判断し、エラーをスローします! 関数の場合は、この配列をトラバースし、コールバック関数を実行してトラバーサルの現在の値、インデックス、およびこの配列を渡し、コールバック関数の戻り値を一時的な空の配列に挿入し、最後にこの一時的な配列を挿入します
return
。
const array1 = [5, 12, 8, 130, 44];
Array.prototype.myMap = function(fun) {
let isFunction = Object.prototype.toString.call(fun) === '[object Function]'
if (!isFunction) {
throw new Error('请传入一个方法。')
}
let temp = []
for (let i = 0; i < this.length; i++) {
let value = fun(this[i], i, this)
temp.push(value)
}
return temp
}
let map1 = array1.myMap(item => item + 2)
let map2 = array1.myMap(item => item / 2)
console.log('array1:', array1)
console.log(map1)
console.log(map2)
逆行
公式説明:reverse()
このメソッドは、配列内の要素の位置を逆にして、配列を返します。配列の最初の要素が最後になり、配列の最後の要素が最初になります。このメソッドは元の配列を変更します。
const sect = ['少林派', '武当派', '逍遥派', '峨眉派', '华山派', '日月神教', '古墓派', '全真教', '丐帮', '明教']
Array.prototype.myReverse = function () {
for (let i = 0; i < this.length / 2; i++) {
let temp = this[i]
let lastIndex = this.length - 1 - i
this[i] = this[lastIndex]
this[lastIndex] = temp
}
return this
}
let reSect = sect.myReverse()
console.log('改变后的数组:', sect)
console.log(reSect)
スライス
公式の説明:slice()
このメソッドは新しい配列オブジェクトを返します。これは、begin と end (begin を含み、end を除く) によって決定される元の配列の浅いコピーです。元の配列は変更されません。
const sect = ['少林派', '武当派', '逍遥派', '峨眉派', '华山派', '日月神教', '古墓派', '全真教', '丐帮', '明教']
Array.prototype.mySlice = function(begin, end) {
let start = begin || 0
let ending = end || this.length
if (begin < 0) {
start = this.length + begin
}
if (end < 0) {
ending = this.length + end
}
let temp = []
for (let i = start; i < ending; i++) {
temp.push(this[i])
}
return temp
}
console.log(sect.mySlice(1, 3))
console.log(sect.mySlice(-2))
いくつかの
公式の説明:some()
このメソッドは、配列内の少なくとも 1 つの要素が提供された関数テストに合格するかどうかをテストします。ブール型の値を返します。
const array1 = [5, 12, 8, 130, 44]
Array.prototype.mySome = function(fun) {
let isFunction = Object.prototype.toString.call(fun) === '[object Function]'
if (!isFunction) {
throw new Error('请传入一个方法。')
}
for (let i = 0; i < this.length; i++) {
let flag = fun(this[i], i, this)
if (flag) {
return true
}
}
return false
}
console.log(array1.mySome(item => item === 130))
console.log(array1.mySome(item => item > 100))
console.log(array1.mySome(item => item > 200))