You can find all the code in this post at repo Github.
Array prototype related challenges
Array.prototype.at()
/**
* @param {number} index
* @return {any | undefiend}
*/
Array.prototype.myAt = function (index) {
const len = this.length;
if (index < -len || index >= len) {
return;
}
return this[(index + len) % len];
};
// Usage example
console.log([1, 2, 3, 4].myAt(2)); // => 3
console.log([1, 2, 3, 4].myAt(-1)); // => 4
console.log([1, 2, 3, 4].myAt(5)); // => undefined
Array.prototype.concat()
/**
* @template T
* @param {...(T | Array<T>)} itemes
* @return {Array<T>}
*/
Array.prototype.myConcat = function (...items) {
const newArray = [...this];
for (const item of items) {
if (Array.isArray(item)) {
newArray.push(...item);
} else {
newArray.push(item);
}
}
return newArray;
};
// Usage example
console.log([1, 2, 3].myConcat([])); // => [1, 2, 3];
console.log([1, 2, 3].myConcat([4, 5, 6, [2]])); // => [1, 2, 3, 4, 5, 6, [2]];
Array.prototype.every()
/**
* @template T
* @param { (value: T, index: number, array: Array<T>) => boolean } callbackFn
* @param {any} [thisArg]
* @return {boolean}
*/
Array.prototype.myEvery = function (callbackFn, thisArg) {
const len = this.length;
let flag = true;
for (let i = 0; i < len; i += 1) {
if (Object.hasOwn(this, i) && !callbackFn.call(thisArg, this[i], i, this)) {
flag = false;
break;
}
}
return flag;
};
// Usage example
console.log([1, 2, 3].myEvery((item) => item > 2)); // => false
console.log([1, 2, 3].myEvery((item) => item > 0)); // => true
Array.prototype.filter()
/**
* @template T, U
* @param { (value: T, index: number, array: Array<T>) => boolean } callbackFn
* @param { any } [thisArg]
* @return {Array<T>}
*/
Array.prototype.myFilter = function (callbackFn, thisArg) {
const newArray = [];
for (let i = 0; i < this.length; i += 1) {
if (Object.hasOwn(this, i) && callbackFn.call(thisArg, this[i], i, this)) {
newArray.push(this[i]);
}
}
return newArray;
};
// Usage example
console.log([1, 2, 3, 4].myFilter((value) => value % 2 == 0)); // => [2, 4]
console.log([1, 2, 3, 4].myFilter((value) => value < 3)); // => [1, 2]
Array.prototype.flat()
/**
* @param { Array } arr
* @param { number } depth
* @returns { Array }
*/
function flatten(arr, depth = 1) {
const newArray = [];
for (let i = 0; i < arr.length; i += 1) {
if (Array.isArray(arr[i]) && depth !== 0) {
newArray.push(...flatten(arr[i], depth - 1));
} else {
newArray.push(arr[i]);
}
}
return newArray;
}
// Usage example
const words = ["spray", "elite", "exuberant", "destruction", "present"];
const result = words.filter((word) => word.length > 6);
console.log(result); // => ["exuberant", "destruction", "present"]
Array.prototype.forEach()
/**
* @template T, U
* @param { (value: T, index: number, array: Array<T>) => U } callbackFn
* @param {any} [thisArg]
* @return {Array<U>}
*/
Array.prototype.myForEach = function (callbackFn, thisArg) {
if (this == null) {
throw new TypeError("this is null or not defined");
}
if (typeof callbackFn !== "function") {
throw new TypeError(callbackFn + " is not a function");
}
const O = Object(this);
// Zero-fill Right Shift to ensure that the result if always non-negative.
const len = O.length >>> 0;
for (let i = 0; i < len; i += 1) {
if (Object.hasOwn(O, i)) {
callbackFn.call(thisArg, O[i], i, O);
}
}
};
// Usage example
console.log(
[1, 2, 3].myForEach((el) => el * el),
null
); // => [1, 4, 9];
Array.prototype.indexOf()
/**
* @param {any} searchElement
* @param {number} fromIndex
* @return {number}
*/
Array.prototype.myIndexOf = function (searchElement, fromIndex = 0) {
const len = this.length;
if (fromIndex < 0) {
fromIndex = Math.max(0, fromIndex + this.length);
}
for (let i = fromIndex; i < len; i += 1) {
if (this[i] === searchElement) {
return i;
}
}
return -1;
}
// Usage example
console.log([1, 2, 3, 4, 5].myIndexOf(3)); // => 2
console.log([1, 2, 3, 4, 5].myIndexOf(6)); // => -1
console.log([1, 2, 3, 4, 5].myIndexOf(1)); // => 0
console.log(['a', 'b', 'c'].myIndexOf('b')); // => 1
console.log([NaN].myIndexOf(NaN)); // => -1 (since NaN !== NaN)
Array.prototype.last()
/**
* @return {null|boolean|number|string|Array|Object}
*/
Array.prototype.myLast = function () {
return this.length ? this.at(-1) : -1;
};
// Usage example
console.log([].myLast()); // => -1;
console.log([1].myLast()); // => 1
console.log([1, 2].myLast()); // => 2
Array.prototype.map()
/**
* @template T, U
* @param { (value: T, index: number, array: Array<T>) => U } callbackFn
* @param {any} [thisArg]
* @return {Array<U>}
*/
Array.prototype.myMap = function (callbackFn, thisArg) {
const len = this.length;
const newArray = Array.from({ length: len });
for (let i = 0; i < len; i += 1) {
if (Object.hasOwn(this, i)) {
newArray[i] = callbackFn.call(thisArg, this[i], i, this);
}
}
return newArray;
};
// Usage example
console.log([1, 2, 3, 4].myMap((i) => i)); // => [1, 2, 3, 4]
console.log([1, 2, 3, 4].myMap((i) => i * i)); // => [1, 4, 9, 16])
Array.prototype.reduce()
/**
* @template T, U
* @param { (previousValue: U, currentValue: T, currentIndex: number, array: Array<T>) => U } callbackFn
* @param {U} [initialValue]
* @return {U}
*/
Array.prototype.myReduce = function (callbackFn, initialValue) {
const hasInitialValue = initialValue !== undefined;
const len = this.length;
if (!hasInitialValue && !len) {
throw new Error("Reduce of empty array with no initial value");
}
let accumulator = hasInitialValue ? initialValue : this[0];
let startingIndex = hasInitialValue ? 0 : 1;
for (let i = startingIndex; i < len; i += 1) {
if (Object.hasOwn(this, i)) {
accumulator = callbackFn(accumulator, this[i], i, this);
}
}
return accumulator;
};
// Usage example
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.myReduce((acc, num) => acc + num, 0);
console.log(sum); // => 15
const products = numbers.myReduce((acc, num) => acc * num, 1);
Array.prototype.some()
/**
* @template T
* @param { (value: T, index: number, array: Array<T>) => boolean } callbackFn
* @param {any} [thisArg]
* @return {boolean}
*/
Array.prototype.mySome = function (callbackFn, thisArg) {
const len = this.length;
let flag = false;
for (let i = 0; i < len; i += 1) {
if (Object.hasOwn(this, i) && callbackFn.call(thisArg, this[i], i, this)) {
flag = true;
break;
}
}
return flag;
};
// Usage example
console.log([1, 2, 3].mySome((item) => item > 2)); // => true
console.log([1, 2, 3].mySome((item) => item < 0)); // => false
Array.prototype.square()
/**
* @return {Array<number>}
*/
Array.prototype.mySquare = function () {
const len = this.length;
const newArray = Array.from({ length: len });
for (let i = 0; i < len; i += 1) {
newArray[i] = this[i] * this[i];
}
return newArray;
};
// Usage example
console.log([1, 2, 3].mySquare()); // => [1, 4, 9];
console.log([].mySquare()); // => [];
Reference
- GreatFrontEnd
- Array.prototype.at() - MDN
- Array.prototype.concat() - MDN
- Array.prototype.every() - MDN
- Array.prototype.filter() - MDN
- Array.prototype.flat() - MDN
- Array.prototype.forEach() - MDN
- Array.prototype.indexOf() - MDN
- Array.prototype.map() - MDN
- Array.prototype.reduce() - MDN
- Array.prototype.some() - MDN
- 2635. Apply Transform Over Each Element in Array - LeetCode
- 2634. Filter Elements from Array - LeetCode
- 2626. Array Reduce Transformation - LeetCode
- 2619. Array Prototype Last - LeetCode
- 2625. Flatten Deeply Nested Array - LeetCode
- 3. implement Array.prototype.flat() - BFE.dev
- 151. implement Array.prototype.map() - BFE.dev
- 146. implement Array.prototype.reduce() - BFE.dev
Top comments (0)