How to write your own Javascript array methods without using any of the Javascript built-in array methods
Introduction
As a JavaScript developer, you might be familiar with the built-in array methods like map
, filter
, reduce
, forEach
, and others. These methods make it easy to manipulate arrays, but have you ever thought about how they work under the hood? What if you had to write your own array methods without using these built-in methods? In this post, we’ll explore how to write your own JavaScript array methods without using the built-in ones.
Before we dive into the implementation, let’s first understand what an array method is. In JavaScript, an array method is a function that operates on each element of an array and returns a new array, a scalar value or modifies the original array.
length
Now, let’s start with the first array function (or method): length
. The length
function is used to get the number of elements in an array. Here’s how you can implement the length
the method from scratch:
/**
* @name length
* @function
*
* @param {String|Object|Array|Number} input input argument
* @param {Number} count initial count
*
* @description input element length
*
* @return {Number} The input element length
*
*/
const length = (input = 'something', count = 0) => {
for (let i = 0; i < input.length; i++) {
count++;
}
return count;
}
The length
function can be called directly. For example, to get the length of an array using this function, you would use the following syntax:
const array = [1, 2, 3, 4];
console.log(length(array)); // Output: 4
isArray
Next, let’s move on to theisArray
function (or method). TheisArray
function is used to determine whether a given value is an array or not. This method returns a boolean value, true if the value is an array, and false otherwise.
TheisArray
function takes one argument, which can be any value. If the argument is an array, the method will return true. If the argument is not an array, the method will return false.
Here’s how you can implement theisArray
function:
/**
* @name isArray
* @function
*
* @param {Array|Object|} input input argument
*
* @description checks if input element is an array
*
* @return {Number} True if input element is an array
*
*/
const isArray = (input = []) => Object.prototype.toString.call(input) === '[object Array]';
Here’s an example that demonstrates how to use theisArray
function:
const myArray = [1, 2, 3, 4];
const notAnArray = 'This is not an array';
console.log(isArray(myArray)); // Output: true
console.log(isArray(notAnArray)); // Output: false
Note that theisArray
function only works for arrays created with the Array
constructor or array literals ([]
). It does not work for arrays created with other constructors or object literals. For example:
const myObj = { a: 1, b: 2 };
const myArray = new Int8Array([1, 2, 3, 4]);
console.log(isArray(myObj)); // Output: false
console.log(isArray(myArray)); // Output: false
push
Next, let’s move on to thepush
function (or method) In JavaScript, thepush
function is used to add one or more elements to the end of an array. Thepush
function modifies the original array and returns the new length of the array. It takes one or more arguments, each representing an element to be added to the end of the array.
 Here’s how you can implement thepush
function:
/**
* @name push
* @function
*
* @param {Array} array input array
* @param {Array|Object|Number} elements elements to push to the array
*
* @description pushes elements to the array
*
* @return {Array} The augmented array
*
*/
const push = (array = [], ...elements) => {
if(!isArray(array)) return array;
for (let i = 0; i < length(elements); i++) {
array[length(array)] = elements[i];
}
return length(array);
}
Here’s an example that demonstrates how to use thepush
function :
const array = [1, 2, 3];
const newArray = push(array, 4, 5);
console.log(array); // Output: [1, 2, 3, 4, 5]
console.log(newArray); // Output: 5
Note that thepush
function can be used to add any type of element to an array, including other arrays, objects, and functions. For example:
const array = [1, 2, 3];
const simpleFunction = () => console.log('hello');
push(array, [4, 5], {a: 6, b: 7}, simpleFunction);
console.log(array); // Output: [1, 2, 3, [4, 5], {a: 6, b: 7}, () => console.log('hello')]
Overall, the push
function is a useful method that allows you to add one or more elements to the end of an array.
concat
Next, let’s move on to theconcat
function (or method). Theconcat
function is used to merge two or more arrays into a single array. Theconcat
function does not modify the original arrays, instead, it returns a new array that contains the elements from all of the arrays passed to it as arguments. Theconcat
function can take any number of arguments, each representing an array.Â
Here’s how you can implement the contact
function:
/**
* @name concat
* @function
*
* @param {Array} array input array
* @param {Array} result the suposed initial array
*
* @description concatenates the input array
*
* @return {Array} The concatenated array
*
*/
const concat = (...args) => {
const result = [];
for (let i = 0; i < length(args); i++) {
const arg = args[i];
if (isArray(arg)) {
for (let j = 0; j < length(arg); j++) {
push(result, arg[j]);
}
} else {
push(result, arg);
}
}
return result;
}
Here’s an example that demonstrates how to use the concat
function:
const array1 = [1, 2, 3];
const array2 = [4, 5, 6];
const array3 = [7, 8, 9];
const newArray = concat(array1, array2, array3);
console.log(newArray); // Output: [1, 2, 3, 4, 5, 6, 7, 8, 9]
Theconcat
function can also be used with non-array values. If you pass a non-array value as an argument to theconcat
method, the value will be converted to an array before it is merged with the other arrays. For example:
const array1 = [1, 2, 3];
const string = 'hello';
const newArray = concat(array1, string);
console.log(newArray); // Output: [1, 2, 3, 'h', 'e', 'l', 'l', 'o']
Overall, the concat
function is a useful function that allows you to merge multiple arrays (and non-array values) into a single array.
flat
Next, let’s move on to theflat
function. The flat
function (or method) is used to flatten an array, which means that it creates a new array with all sub-array elements concatenated into it recursively up to the specified depth. The flat
method does not modify the original array but returns a new flattened array.
Theflat
function takes two optional arguments: the first specifies the depth of flattening and the second the new array or return array. By default, the depth is 1, which means that the method only flattens one level of sub-arrays. If you pass a value of 2 or greater as the argument, the method will recursively flatten up to that depth.
 Here’s how you can implement the flat
method:
/**
* @name flat
* @function
*
* @param {Array|Object} array the array to filter
* @param {Number} depth the flat level or flat depth
* @param {Array|Object} result the suposed initial flattened array
*
* @description flattens an array
*
* @return {Array|Object} The flattened result array
*
*/
const flat = (array = [], depth = 1, result = []) => {
for (var i = 0; i < length(array); i++) {
if ((isArray(array[i])) && depth > 0) {
result = concat(result, flat(array[i], depth - 1))
} else {
push(result,array[i]);
}
}
return result;
}
Here’s an example that demonstrates how to use the flat
function:
const array = [1, 2, [3, 4], [5, [6, 7]]];
const flattenedArray = flat(array);
console.log(flattenedArray); // Output: [1, 2, 3, 4, 5, 6, 7]
The flat
function recursively concatenates all elements of the sub-arrays into a single array. The result is a new array that contains all the elements of array
at a depth of 1.
Note that the flat
function does not modify the original array. Instead, it returns a new flattened array.
The flat
function can also be used with sparse arrays, which are arrays with empty slots. In this case, the empty slots are removed from the flattened array. For example:
const array = [1, 2, , 4, [5, , 7]];
const flattenedArray = flat(array);
console.log(flattenedArray); // Output: [1, 2, 4, 5, 7]
Overall, the flat
function is a useful method that allows you to flatten an array into a new array, recursively concatenating all elements of sub-arrays.
filter
Next, let’s move on to the filter
function (or method). The filter
function is used to create a new array that contains all the elements of the original array that meet a certain condition. The filter
function does not modify the original array but returns a new array containing only the elements that pass the condition specified in the callback function.
The filter
function takes a callback function as its argument, which is executed once for each element in the array. The callback function should return a boolean value, which determines whether the element should be included in the new array.
Here’s how you can implement the filter
method:
/**
* @name filter
* @function
*
* @param {Array|Object} array the array to filter
* @param {Function|Object} fn A function to execute for each element in the array.
* It should return a truthy value to keep the element in the resulting array, and a falsy value otherwise.
* @param {Array|Object} result the suposed initial filtered array
*
* @description filters an array
*
* @return {Array|Object} array, the filtered array
*
*/
const filter = (array = [], fn = () => {}, result = []) => {
if(!isArray(array)) throw new TypeError(`${array} must be an array`);
for(let i = 0; i < length(array); i++){
if(fn(array[i],i,array)) push(result,array[i]);
if(isArray(array[i])) filter(array[i], fn, result)
}
return result;
}
Here’s an example that demonstrates how to use the filter
function:
const array = [1, 2, 3, 4, 5];
const filteredArray = filter(array, (element, index, array) => {
return element > 2;
});
console.log(filteredArray); // Output: [3, 4, 5]
Note that the filter
function does not modify the original array (array
). Instead, it returns a new array (filteredArray
) that contains only the elements that passed the condition specified in the callback function.
The filter
function can also be used with objects. In this case, the callback function should reference a property of the object. For example:
const array = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Charlie', age: 35 },
];
const filteredArray = filter(array, (person, index, array) => {
return person.age > 30;
});
console.log(filteredArray); // Output: [{ name: 'Charlie', age: 35 }]
Overall, the filter
function is a powerful method that allows you to create a new array containing only the elements of the original array that meet a certain condition.
map
Next, let’s move on to the map
function. The map
function is used to create a new array with the same length as the original array but with each element transformed based on a provided callback function. The map
function does not modify the original array but returns a new array with the transformed elements.
The map
function takes a callback function as its argument, which is executed once for each element in the array. The callback function should return a transformed value for each element.
Here’s how you can implement the map
method:
/**
* @name map
* @function
*
* @param {Array|Object} array the array to filter
* @param {Function|Object} fn A function to execute for each element in the array.
* It should return a truthy value to keep the element in the resulting array, and a falsy value otherwise.
* @param {Array|Object} result the suposed initial filtered array
*
* @description maps an array
*
* @return {Array|Object} the resulted mapped array
*
*/
const map = (array = [], fn = () => {}, result = []) => {
if(!isArray(array)) throw new TypeError(`${array} must be an array`);
for(let i = 0; i < length(array); i++){
if(fn(array[i],i, array)) push(result,fn(array[i],i, array))
if(isArray(array[i])) map(array[i], fn, result)
}
return result;
}
Here’s an example that demonstrates how to use the map
function:
const array = [1, 2, 3, 4];
const transformedArray = map(array,(element, index, array) => {
return element * 2;
});
console.log(transformedArray); // Output: [2, 4, 6, 8]
Note that the map
function does not modify the original array (array
). Instead, it returns a new array (transformedArray
) with the transformed elements.
The map
function can also be used with objects. In this case, the callback function should reference a property of the object. For example:
const array = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Charlie', age: 35 },
];
const transformedArray = map(array, (person, index, array) => {
return person.age;
});
console.log(transformedArray); // Output: [25, 30, 35]
Overall, the map
function is a powerful function that allows you to create a new array with each element transformed based on a provided callback function.
forEach
Next, let’s move on to the forEach
function (or method). The forEach
function is used to execute a provided function once for each element in an array. The forEach
function does not modify the original array, but it provides an easy way to iterate through an array and perform a certain operation on each element.
The forEach
function takes a callback function as its argument, which is executed once for each element in the array. The callback function can take up to three arguments: the current element being processed, the index of the current element, and the array being traversed.
Here’s how you can implement the forEach
function:
/**
* @name forEach
* @function
*
* @param {Array|Object} array the array to filter
* @param {Function|Object} fn A function to execute for each element in the array.
* It should return a truthy value to keep the element in the resulting array, and a falsy value otherwise.
*
* @description maps an array
*
* @return Does not return anything
*
*/
const forEach = (array = [], fn = () => {}) => {
if(!isArray(array)) throw new TypeError(`${array} must be an array`);
for(let i = 0; i < length(array); i++){
fn(array[i],i, array);
}
}
Here’s an example that demonstrates how to use the forEach
function:
const array = [1, 2, 3, 4];
forEach(array, (element, index, array) => {
console.log(`Element ${index}: ${element}`);
});
Note that the forEach
function does not modify the original array (myArray
). Instead, it provides an easy way to iterate through an array and perform a certain operation on each element.
The forEach
function is particularly useful when you need to perform the same operation on each element in an array, such as updating a user interface or performing a calculation. It can also be used to execute asynchronous code on each element, such as making API requests.
Overall, the forEach
function is a useful function that allows you to loop through each element in an array and perform a certain operation on each element.
reduce
Next, let’s move on to the reduce
function. The reduce
function is used to reduce an array to a single value by executing a provided function for each element in the array. The reduce
function can be used to perform a variety of operations on an array, such as calculating a sum, finding the maximum value, or concatenating a string.
The reduce
function takes two arguments: a callback function and an optional initial value. The callback function is executed for each element in the array and should return a new value, which is used as the accumulator for the next iteration. The initial value is the starting value for the accumulator. If no initial value is provided, the first element in the array is used as the initial value.
Here’s how you can implement the reduce
method:
/**
* @name reduce
* @function
*
* @param {Array|Object} array the array to filter
* @param {Function|Object} fn A function to execute for each element in the array.
* It should return a truthy value to keep the element in the resulting array, and a falsy value otherwise.
* @param {Array|Object|Number|String} initialValue The initial value
*
* @description reduces an array
*
* @return {Array|Object|Number|String} The result
*
*/
const reduce = (array = [], fn = () => {}, initialValue = undefined) =>{
let accumulator = initialValue === undefined ? array[0] : initialValue;
const startingIndex = initialValue === undefined ? 1 : 0;
for (let i = startingIndex; i < length(array); i++) {
accumulator = fn(accumulator, array[i], i, array);
}
return accumulator;
}
Here’s an example that demonstrates how to use the reduce
function:
const array = [1, 2, 3, 4];
const sum = reduce(array, (accumulator, currentValue, index, array) => {
return accumulator + currentValue;
}, 0);
console.log(sum); // Output: 10
Note that the reduce
function can also be used without an initial value. In this case, the first element in the array is used as the initial value, and the callback function starts with the second element in the array. For example:
const array = [1, 2, 3, 4];
const sum = myArray.reduce((accumulator, currentValue, index, array) => {
return accumulator + currentValue;
});
console.log(sum); // Output: 10
Overall, the reduce
function is a powerful method in JavaScript that allows you to reduce an array to a single value by executing a provided function for each element in the array.
every
Next, let’s move on to the every
function. The every
function is used to test whether all elements in an array pass a certain condition. The every
function returns a boolean value (true
or false
) indicating whether all elements in the array pass the condition.
The every
function takes a callback function as its argument, which is executed once for each element in the array. The callback function should return a boolean value, which determines whether the element passes the condition or not.
Here’s how you can implement the every
function:
/**
* @name every
* @function
*
* @param {Array|Object} array the array to filter
* @param {Function|Object} fn A function to execute for each element in the array.
* It should return a truthy value to keep the element in the resulting array, and a falsy value otherwise.
*
* @description Check is fn is true for each element
*
* @return {Boolean} The result
*
*/
const every = (array = [], fn = () => {}) => {
if(!isArray(array)) throw new TypeError(`${array} must be an array`);
for(let i = 0; i < length(array); i++){
if(fn(array[i], i, array) === false) return false;
if(isArray(array[i])) every(array[i],fn);
}
return true;
}
Here’s an example that demonstrates how to use the every
function:
const array = [2, 4, 6, 8];
const isEven = every(array, (element, index, array) => {
return element % 2 === 0;
});
console.log(isEven); // Output: true
Note that the every
function stops iterating through the array as soon as it encounters an element that does not pass the condition. This can be useful for optimizing performance, especially for large arrays.
The every
function can also be used with objects. In this case, the callback function should reference a property of the object. For example:
const array = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Charlie', age: 35 },
];
const isOverTwenty = every(array, (person, inddex, array) => {
return person.age > 20;
});
console.log(isOverTwenty); // Output: true
Overall, the every
function is a useful function that allows you to test whether all elements in an array pass a certain condition.
some
Next, let’s move on to the some
function. The some
function is used to test whether at least one element in an array passes a certain condition. The some
function returns a boolean value (true
or false
) indicating whether at least one element in the array passes the condition.
The some
fuction takes a callback function as its argument, which is executed once for each element in the array. The callback function should return a boolean value, which determines whether the element passes the condition or not.
Here’s how you can implement the some
function:
/**
* @name some
* @function
*
* @param {Array|Object} array the array to filter
* @param {Function|Object} fn A function to execute for each element in the array.
* It should return a truthy value to keep the element in the resulting array, and a falsy value otherwise.
*
* @description Check is fn is true for at least one element
*
* @return {Boolean} The result
*
*/
const some = (array = [], fn = () => {}) => {
if(!isArray(array)) throw new TypeError(`${array} must be an array`);
for(let i = 0; i < length(array); i++){
if(fn(array[i],i, array)) return true;
if(isArray(array[i])) some(array[i],fn);
}
return false;
}
Here’s an example that demonstrates how to use the some
function:
const array = [1, 3, 5, 7];
const isEven = some(array, (element, index, array) => {
return element % 2 === 0;
});
console.log(isEven); // Output: false
Note that the some
function stops iterating through the array as soon as it encounters an element that passes the condition. This can be useful for optimizing performance, especially for large arrays.
The some
function can also be used with objects. In this case, the callback function should reference a property of the object. For example:
const array = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Charlie', age: 35 },
];
const isOverThirty = some(array, (person, index, array) => {
return person.age > 30;
});
console.log(isOverThirty); // Output: true
Overall, the some
function is a useful method in JavaScript that allows you to test whether at least one element in an array passes a certain condition.
findIndex
Next, let’s move on to the findIndex
method. The findIndex
function is used to find the index of the first element in an array that passes a certain condition. The findIndex
function returns the index of the first element that passes the condition, or -1
if no element passes the condition.
The findIndex
function takes a callback function as its argument, which is executed once for each element in the array. The callback function should return a boolean value, which determines whether the element passes the condition or not.
.Here’s how you can implement the findIndex
function:
/**
* @name findIndex
* @function
*
* @param {Array|Object} array the array to filter
* @param {Function|Object} fn A function to execute for each element in the array.
* It should return a truthy value to keep the element in the resulting array, and a falsy value otherwise.
*
* @description Finds the index of an element in the array
*
* @return {Number} The index of the found element
*
*/
const findIndex = (array = [], fn = () => {}) => {
if(!isArray(array)) throw new TypeError(`${array} must be an array`);
for (let i = 0; i < length(array); i++) {
if (fn(array[i], i, array)) return i;
if(isArray(array[i])) findIndex(array[i], fn);
}
return -1;
}
Note that the findIndex
function stops iterating through the array as soon as it encounters an element that passes the condition. This can be useful for optimizing performance, especially for large arrays.
The findIndex
function can also be used with objects. In this case, the callback function should reference a property of the object. For example:
const array = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Charlie', age: 35 },
];
const index = findIndex(array, (person, index, array) => {
return person.age > 30;
});
console.log(index); // Output: 2
Here’s an example that demonstrates how to use the findIndex
function:
const array = [2, 4, 6, 8];
const index = findIndex(array, (element, index, array) => {
return element > 5;
});
console.log(index); // Output: 2
Overall, the findIndex
function is a useful function that allows you to find the index of the first element in an array that passes a certain condition.
find
Next, let’s move on to the find
method. The find
function is used to find the first element in an array that passes a certain condition. The find
method returns the first element that passes the condition, or undefined
if no element passes the condition.
The find
function takes a callback function as its argument, which is executed once for each element in the array. The callback function should return a boolean value, which determines whether the element passes the condition or not.
. Here’s how you can implement the find
function:
/**
* @name find
* @function
*
* @param {Array|Object} array the array to filter
* @param {Function|Object} fn A function to execute for each element in the array.
* It should return a truthy value to keep the element in the resulting array, and a falsy value otherwise.
*
* @description Finds an elment or elments in the given array
*
* @return {String|Object|Array|Number|Boolean} The element or elments found
*
*/
const find = (array = [], fn = () => {}) => {
if(!isArray(array)) throw new TypeError(`${array} must be an array`);
for (let i = 0; i < length(array); i++) {
if (fn(array[i], i, array)) return array[i];
if (isArray(array[i])) find(array[i], fn);
}
return undefined;
}
Here’s an example that demonstrates how to use the find()
function:
const array = [2, 4, 6, 8];
const element = find(array, (element, index, array) => {
return element > 5;
});
console.log(element); // Output: 6
Note that the find
function stops iterating through the array as soon as it encounters an element that passes the condition. This can be useful for optimizing performance, especially for large arrays.
The find
function can also be used with objects. In this case, the callback function should reference a property of the object. For example:
const array = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Charlie', age: 35 },
];
const element = find(array, (person, index, array) => {
return person.age > 30;
});
console.log(element); // Output: { name: 'Charlie', age: 35 }
Overall, the find
function is a useful function that allows you to find the first element in an array that passes a certain condition.
entries
Next, let’s move on to the entries
function. The fentries
function is used to return an array iterator object with key-value pairs of the array’s entries. Each entry is represented as a two-element array containing the index and the corresponding element value.
The entries
function returns a new array iterator object, which can be used to loop through the entries of the original array using a for...of
loop or the next
function.
Here’s how you can implement the entries
method:
/**
* @name entries
* @function
*
* @param {Array|Object} array the input array
* @param {Array} result the result array
*
* @description Finds entries in the given array
*
* @return {Array} The result array
*
*/
const entries = (array = [], result = []) => {
if(!isArray(array)) throw new TypeError(`${array} must be an array`);
for (let i = 0; i < length(array); i++) {
push(result,[i, array[i]]);
//if(isArray(array[i])) entries(array[i], result);
}
return result;
}
Note that the resulting iterator contains the same key-value pairs as the iterator produced by the built-in Array.entries
method. However, this implementation does not handle sparse arrays in the same way as the built-in method. It also does not support the optional thisArg
parameter. Nonetheless, it provides a basic example of how to create an iterator of key-value pairs from an array using JavaScript.
Here’s an example that demonstrates how to use the entries
function:
const array = ['apple', 'banana', 'cherry'];
const arrayEntries = entries(array);
for (const [index, value] of arrayEntries) {
console.log(`${index}: ${value}`);
}
/*
Output:
0: apple
1: banana
2: cherry
*/
fill
Next, let’s move on to the fill
function. The fill
 function is used to fill all the elements of an array with a static value. The fill
function takes up to four arguments: the input array, the value to fill the array with, the starting index to fill from (optional), and the ending index to fill to (optional).
Here’s how you can implement the fill
function:
/**
* @name fill
* @function
*
* @param {Array|Object} array the input array
* @param {String|Number} value the value to fill in with
* @param {Number} start the start index
* @param {Number} len the len of the input array
*
* @description Fill in the given array with the input values
*
* @return {Array} The filled array
*
*/
const fill = (array = [], value = 0, start = 0, end = length(array)) => {
if(!isArray(array)) throw new TypeError(`${array} must be an array`);
for (let i = start; i < end; i++) {
array[i] = value;
if(isArray(array[i])) fill(array[i], value, start, end);
}
return array;
}
Here’s an example that demonstrates how to use the fill
fill:
const aray = [1, 2, 3, 4, 5];
fill(array, 0);
console.log(myArray); // Output: [0, 0, 0, 0, 0]
Here’s an example that demonstrates how to use the fill
function with starting and ending indices:
const array = [1, 2, 3, 4, 5];
fill(array, 0, 2, 4);
console.log(Array); // Output: [1, 2, 0, 0, 5]
Overall, the fill
function is a useful function that allows you to fill all the elements of an array with a static value, with optional starting and ending indices.
from
Next, let’s move on to the from
 function (or method). The from
function is used to create a new array from an array-like or iterable object. An array-like object is an object that has a length property and indexed elements but is not necessarily an array (e.g., the arguments
object or a NodeList
object). An iterable object is an object that can be iterated over using a for...of
loop (e.g., an array, a Map
object, or a Set
object).
The from
function takes four arguments with the third one being optional arguments: an interable
function, a mapFn
function, and a thisArg
object. The mapFn
function is used to map each element of the input object to a new value, and the thisArg
value is used as the this
context for the mapFn
function.
Here’s how you can implement the from
method:
/**
* @name from
* @function
*
* @param {Array|Object} interable the input object to convert
* @param {Function} mapFn the function to map the input object
* @param {Object} thisArg The argument to map the input object
* @param {Array} result the result object
*
* @description Creates a new array from an array-like or iterable object
*
* @return {Array} The result array.
*
*/
function from(iterable,mapFn,thisArg, result = []) {
if (iterable == null) throw new TypeError(`Cannot convert ${iterable} to an array`);
const iterator = iterable[Symbol.iterator]();
for (let i = 0; i < length(iterable); i++) {
const value = mapFn ? mapFn.call(thisArg, iterator.next().value, i) : iterator.next().value;
push(result, value);
}
return result;
}
Here’s an example that demonstrates how to use the from
function to create a new array from an iterable object:
const mySet = new Set(['apple', 'banana', 'cherry']);
const array = from(mySet);
console.log(array); // Output: ['apple', 'banana', 'cherry']
includes
Next, let’s move on to the includes
function. The includes
function is used to determine whether an array includes a certain value. The method returns a boolean value (true
or false
) indicating whether the value was found in the array or not.
The includes
function takes two required arguments: the input array and the search value which is the value to search for in the array. It also takes two optional second arguments: the index at which to begin the search and the length of the array.
Here’s how you can implement the includes
method:
/**
* @name includes
* @function
*
* @param {Array|Object} array the input array
* @param {String|Number} searchElement the search value
* @param {Number} fromIndex the start index
* @param {Number} len the len of the input array
*
* @description Checks whether the input array contains the specified search element
*
* @return {Boolean} True if the input array contains the searchElement
*
*/
const includes = (array = [], searchElement = '', fromIndex = 0, len = length(array)) => {
if(!isArray(array)) throw new TypeError(`${array} must be an array`);
let startIndex = fromIndex || 0;
if (startIndex < 0) startIndex = len + startIndex;
for (let i = startIndex; i < len; i++) {
if (array[i] === searchElement) return true;
}
return false;
}
Here’s an example that demonstrates how to use the includes
function:
const array = [1, 2, 3, 4, 5];
const result1 = includes(array, 3);
const result2 = includes(array, 6);
console.log(result1); // Output: true
console.log(result2); // Output: false
Here’s an example that demonstrates how to use the includes
function with a starting index:
const array = [1, 2, 3, 4, 5];
const result1 = includes(array, 3, 2);
const result2 = includes(array, 3, 3);
console.log(result1); // Output: true
console.log(result2); // Output: false
Overall, the includes
function is a useful function that allows you to determine whether an array includes a certain value, with an optional starting index.
indexOf
Next, let’s move on to the indexOf
function. The indexOf
function is used to find the index of the first occurrence of a specified value in an array. If the specified value is not found in the array, the function returns -1
.
The indexOf
function takes one required argument, which is the value to search for in the array. It also takes an optional second argument, which is the index at which to begin the search.
Here’s how you can implement the indexOf
method:
/**
* @name indexOf
* @function
*
* @param {Array|Object} array the input array
* @param {String|Number} searchElement the search value
* @param {Number} fromIndex the start index
* @param {Number} len the len of the input array
*
* @description Find the index of the first occurrence of the search value
*
* @return {Number} The index of the first occurrence of the search value
*
*/
const indexOf = (array = [], searchElement = '', fromIndex = 0, len = length(array)) => {
if(!isArray(array)) throw new TypeError(`${array} must be an array`);
let startIndex = fromIndex || 0;
if (startIndex < 0) startIndex = len + startIndex;
for (let i = startIndex; i < len; i++) {
if (array[i] === searchElement) return i;
if(isArray(array[i])) indexOf(array[i], searchElement, fromIndex, len);
}
return -1;
}
Here’s an example that demonstrates how to use the indexOf
function:
const array = [1, 2, 3, 4, 5];
const index1 = indexOf(array, 3);
const index2 = indexOf(array, 6);
console.log(index1); // Output: 2
console.log(index2); // Output: -1
Here’s an example that demonstrates how to use the indexOf
function with a starting index:
const array = [1, 2, 3, 4, 5];
const index1 = indexOf(array, 3, 2);
const index2 = indexOf(array, 3, 3);
console.log(index1); // Output: 2
console.log(index2); // Output: -1
Overall, the indexOf
function is a useful function that allows you to find the index of the first occurrence of a specified value in an array, with an optional starting index.
join
Next, let’s move on to the join
method. The join
function is used to create a new string by concatenating all the elements of an array, separated by a specified separator string. If no separator is provided, the default separator is a comma.
The join
function takes one optional argument, which is the separator string to use to separate the array elements. If the separator argument is not provided, the default separator (a comma) is used.
Here’s how you can implement the join
function:
/**
* @name join
* @function
*
* @param {Array|Object} array the input array
* @param {String|Number} separator the separator
* @param {Number} len the length of the input array
* @param {String} result the result string
*
* @description Join the input array
*
* @return {String} The result string
*
*/
const join = (array = [], separator = ' ', len = length(array), result = '') => {
if(!isArray(array)) throw new TypeError(`${array} must be an array`);
for (let i = 0; i < len; i++) {
result += array[i];
if (i !== len - 1) result += separator || ',';
if(isArray(array[i])) join(array[i], separator);
}
return result;
}
Here’s an example that demonstrates how to use the join
function:
const array = ['apple', 'banana', 'cherry'];
const result1 = join(array);
const result2 = join(array,'-');
console.log(result1); // Output: "apple,banana,cherry"
console.log(result2); // Output: "apple-banana-cherry"
Overall, the join
function is a useful function that allows you to create a new string by concatenating all the elements of an array, separated by a specified separator string.
keys
Next, let’s move on to the keys
method. The keys
function is used to create a new array iterator object that contains the keys of an array. The iterator object can be used to loop through the keys of the array using a for...of
loop.
The keys
function takes two arguments: the input array, and the optional index
Here’s how you can implement the keys
function:
/**
* @name keys
* @function
*
* @param {Array|Object} array the input array
* @param {Number} nextIndex the index of the next
*
* @description Finds keys in the input array
*
* @return {Object} the result object with keys as an interation object
*
*/
const keys = (array = [], nextIndex = 0) => {
if(!isArray(array)) throw new TypeError(`${array} must be an array`);
return {
next: function() {
return nextIndex < length(array) ?
{ value: nextIndex++, done: false } :
{ value: undefined, done: true };
}
};
}
Here’s an example that demonstrates how to use the keys
function:
const array = ['apple', 'banana', 'cherry'];
const keys = keys(array);
for (const index of keys) {
console.log(index);
}
/**
Output:
0
1
2
*/
Overall, the keys
function is a useful function that allows you to create a new array iterator object containing the keys of an array.
lastIndexOf
Next, let’s move on to the lastIndexOf
method. The lastIndexof
function is used to find the index of the last occurrence of a specified value in an array. If the specified value is not found in the array, the method returns -1
.
The lastIndexOf
function takes one required argument, which is the value to search for in the array. It also takes an optional second argument, which is the index at which to begin the search.
Here’s how you can implement the lastIndexOf
function:
/**
* @name lastIndexOf
* @function
*
* @param {Array|Object} array the input array
* @param {String|Number} searchElement the search value
* @param {Number} fromIndex the start index
* @param {Number} len the len of the input array
*
* @description Find the last index of the first occurrence of the search value
*
* @return {Number} The last index of the first occurrence of the search value
*
*/
const lastIndexOf = (array = [], searchElement, fromIndex, len = length(array)) => {
if(!isArray(array)) throw new TypeError(`${array} must be an array`);
let startIndex = fromIndex || len - 1;
if (startIndex < 0) startIndex = len + startIndex;
for (let i = startIndex; i >= 0; i--) {
if (array[i] === searchElement) return i;
if(isArray(array[i])) lastIndexOf(array[i], searchElement, fromIndex);
}
return -1;
}
Here’s an example that demonstrates how to use the lastIndexOf
function:
const array = [1, 2, 3, 4, 5];
const index1 = lastIndexOf(array,3);
const index2 = lastIndexOf(array,6);
console.log(index1); // Output: 2
console.log(index2); // Output: -1
Here’s an example that demonstrates how to use the lastIndexOf
function with a starting index:
const array = [1, 2, 3, 4, 5];
const index1 = lastIndexOf(array,3, 2);
const index2 = lastIndexOf(array,3, 3);
console.log(index1); // Output: 2
console.log(index2); // Output: -1
Overall, the lastIndexOf
function is a useful function that allows you to find the index of the last occurrence of a specified value in an array, with an optional starting index.
reduceRight
reduceRight
Next, let’s move on to the reduceRight
function (or method). The reduceRight
function is similar to the reduce
function, but it works from right-to-left instead of left-to-right. The function applies a function to each element of an array (starting from the rightmost element) and returns a single value. The reduceRight()
function takes two arguments: a callback function and an optional initial value.
The callback function takes four arguments: the accumulator, the current element, the current index, and the array being processed. The accumulator is the value returned by the previous iteration of the callback function, or the initial value if it was provided. The current element is the current element being processed in the array. The current index is the index of the current element being processed. The array being processed is the array that the reduceRight
function was called on.
Here’s how you can implement the reduceRight
method:
/**
* @name reduceRight
* @function
*
* @param {Array|Object} array the array to filter
* @param {Function|Object} fn A function to execute for each element in the array.
* It should return a truthy value to keep the element in the resulting array, and a falsy value otherwise.
* @param {Array|Object|Number|String} initialValue The initial value
*
* @description right reduces an array
*
* @return {Array|Object|Number|String} The result
*
*/
const reduceRight = (array = [], fn = () => {}, initialValue, len = length(array)) => {
if(!isArray(array)) throw new TypeError(`${array} must be an array`);
let accumulator = initialValue === undefined ? array[len - 1] : initialValue;
let startIndex = initialValue === undefined ? len - 2 : len - 1;
if (len === 0 && initialValue === undefined) throw new TypeError('Reduce of empty array with no initial value');
for (let i = startIndex; i >= 0; i--) {
accumulator = fn(accumulator, array[i], i, array);
}
return accumulator;
}
Here’s an example that demonstrates how to use the reduceRight
function:
const array = [1, 2, 3, 4, 5];
const result = reduceRight(array, (accumulator, currentValue,index, array) => {
return accumulator + currentValue;
}, 0);
console.log(result); // Output: 15
Overall, the reduceRight
function is a useful function that allows you to apply a function to each element of an array from right-to-left and return a single value.
reverse
Next, let’s move on to the reverse
function. The reverse
function is used to reverse the order of the elements in an array. This function modifies the original array in place and returns a reference to the same array.
The reverse
function works by swapping the positions of the elements in the array. The first element is swapped with the last element, the second element is swapped with the second-to-last element, and so on until all elements have been swapped.Â
If the array has an odd number of elements, the middle element remains in place because it has no element to swap with.
Here’s how you can implement the reverse
function:
/**
* @name reverse
* @function
*
* @param {Array|Object} array the array to reverse
* @param {Number} len the len of the input array
*
* @description Reverse the input array
*
* @return {Array} The result of the reversed array
*
*/
const reverse = (array = [], len = length(array)) => {
if(!isArray(array)) throw new TypeError(`${array} must be an array`);
const mid = Math.floor(len / 2);
for (let i = 0; i < mid; i++) {
const temp = array[i];
array[i] = array[len - 1 - i];
array[len - 1 - i] = temp;
if(isArray(array[i])) reverse(array[i], len);
}
return array;
}
Here’s an example of using reverse
:
const array = [1, 2, 3];
reverse(array);
console.log(array); // [3, 2, 1]
Note that reverse
modifies the original array in place, so be careful when using it.Â
shift
Next, let’s move on to the shift
function. The shift
function is used to remove the first element from an array and return it. This method modifies the original array in place and returns the removed element. If the array is empty, undefined
is returned.
Here’s how you can implement the shift
function:
/**
* @name shift
* @function
*
* @param {Array|Object} array the array to reverse
* @param {Number} len the len of the input array
* @param {Array|Object|Number|Boolean} firstElement the first element of the input array
*
* @description Reverse the input array
*
* @return {Array} The result of the reversed array
*
*/
const shift = (array = [], len = length(array), firstElement = array[0]) => {
if(!isArray(array)) throw new TypeError(`${array} must be an array`);
if (len === 0) return undefined;
for (let i = 1; i < len; i++) {
array[i - 1] = array[i];
}
array.length = len - 1;
return firstElement;
}
Here’s an example of using the shift
function:
const array = [1, 2, 3];
const firstElement = shift(array);
console.log(array); // [2, 3]
console.log(firstElement); // 1
Note that shift
modifies the original array in place, so be careful when using it.Â
slice
Next, let’s move on to the slice
function. The slice
function is used to create a shallow copy of a portion of an array into a new array object. The original array is not modified.
Here’s how you can implement the slice
function:
/**
* @name slice
* @function
*
* @param {Array|Object} array the array to reverse
* @param {Number} len the len of the input array
* @param {Array} result the result of the slice operation
*
* @description Slices the input array
*
* @return {Array} The result of the sliced array
*
*/
const slice = (array = [], len = length(array), result = []) => {
if(!isArray(array)) throw new TypeError(`${array} must be an array`);
const startIndex = start === undefined ? 0 : start < 0 ? len + start : start;
const endIndex = end === undefined ? len : end < 0 ? len + end : end;
for (let i = startIndex; i < endIndex; i++) {
push(result, arr[i]);
if(isArray(array[i])) slice(array[i], len, result);
}
return result;
}
Here’s an example of using slice
:
const array = [1, 2, 3, 4, 5];
const slicedArr = slice(array,1, 4);
console.log(slicedArr); // [2, 3, 4]
Note that the slice
function creates a shallow copy of the original array. This means that if the original array contains reference values (such as objects or arrays), the copied array will contain references to the same values, rather than new copies of those values.
const array = [1, 2, 3, {name: 'John'}, [4, 5]];
const slicedArr = slice(array,2);
console.log(slicedArr); // [3, {name: 'John'}, [4, 5]]
slicedArr[1].name = 'Jane';
console.log(slicedArr); // [3, {name: 'Jane'}, [4, 5]]
console.log(array); // [1, 2, 3, {name: 'Jane'}, [4, 5]]
In this example, the slice
function creates a new array called slicedArr
that contains a copy of the elements from index 2
to the end of the array
array. However, since one of the copied values is an object, both the array
and slicedArr
arrays contain references to the same object. Therefore, when we modify the object through slicedArr
, the change is reflected in array
as well.
splice
Next, let’s move on to the splice
function. The splice
function is used to modify an array by adding, removing, and/or replacing elements. This method modifies the original array in place and returns an array containing the elements that were removed.
Here’s how you can implement the splice
function:
/**
* @name splice
* @function
*
* @param {Array|Object} array the array to reverse
* @param {Number} start the len of the input array
* @param {Number} deleteCount the result of the slice operation
* @param {Number|Array} items the number of items
*
* @description Splices the input array
*
* @return {Array} The result of the spliced array
*
*/
const splice = (array = [], start = 0, deleteCount = 0, ...items) => {
if(!isArray(array)) throw new TypeError(`${array} must be an array`);
const len = length(array);
const startIndex = start < 0 ? len + start : start;
const numDelete = deleteCount === undefined ? len - startIndex : deleteCount;
const deletedItems = [];
for (let i = startIndex; i < startIndex + numDelete; i++) {
push(deletedItems, array[i]);
}
const numInsert = length(items);
const numTail = len - startIndex - numDelete;
if (numInsert < numDelete) {
for (let i = startIndex; i < startIndex + numInsert; i++) {
array[i] = items[i - startIndex];
}
for (let i = startIndex + numInsert; i < len; i++) {
array[i] = array[i + numDelete - numInsert];
}
array.length = len - numDelete + numInsert;
} else if (numInsert > numDelete) {
array.length = len + numInsert - numDelete;
for (let i = len - 1; i >= startIndex + numDelete; i--) {
array[i + numInsert - numDelete] = array[i];
}
for (let i = 0; i < numInsert; i++) {
array[startIndex + i] = items[i];
}
} else {
for (let i = 0; i < numInsert; i++) {
array[startIndex + i] = items[i];
}
}
return deletedItems;
}
Here’s an example of using splice
:
const array = [1, 2, 3, 4, 5];
const removedItems = splice(array, 2, 2, 'a', 'b');
console.log(array); // [1, 2, 'a', 'b', 5]
console.log(removedItems); // [3, 4]
Note that splice
modifies the original array in place, so be careful when using it. If you need to modify an array without modifying the original, you can use the slice
method to create a copy of the array and then call splice
on the copy:
const array = [1, 2, 3, 4, 5];
const copy = slice(array);
const removedItems = splice(copy, 2, 2, 'a', 'b');
console.log(array); // [1, 2, 3, 4, 5]
console.log(copy); // [1, 2, 'a', 'b', 5]
console.log(removedItems); // [3, 4]
Note that splice
does not create a new array; it modifies the original array in place. So in this example, array
and copy
are two separate arrays with the same elements.
sort
Next, let’s move on to the sort
function. The sort
function is used to sort the elements of an array in place and return the sorted array. The sorting is performed based on the Unicode code points of the elements, by default.
The sort
function takes an array and a callback function as parameters. The callback function is used to compare the values in the array during the sorting process. The quickSort
function is an implementation of the quicksort algorithm, which recursively partitions the array and swaps values until it is sorted. The partition
function chooses a pivot value and compares it to each value in the array, swapping values until the pivot is in its final position. The swap
function simply swaps two values in the array. The sort
function then calls the quickSort
function with the initial left and right indices of the array and returns the sorted array.
Here’s how you can implement the sort
function:
/**
* @name sort
* @function
*
* @param {Array|Object} array the array to reverse
* @param {Function|Object} fn A function to execute for each element in the array.
*
* @description Sorts the input array
*
* @return {Array} The result of the sorted array
*
*/
const sort = (array = [], fn = () => {}) => {
// check if array is an array and callback is a function
if (!isArray(array) || typeof fn !== 'function') return undefined;
// quicksort implementation
const quickSort = (qArray = [], left = 0, right = length(qArray) - 1) => {
if (left >= right) {
return;
}
let pivotIndex = partition(qArray, left, right);
quickSort(qArray, left, pivotIndex - 1);
quickSort(qArray, pivotIndex + 1, right);
}
const partition = (pArray = [], left = 0, right = length(pArray) - 1) => {
let pivotIndex = Math.floor((left + right) / 2);
let pivotValue = pArray[pivotIndex];
swap(pArray, pivotIndex, right);
let storeIndex = left;
for (let i = left; i < right; i++) {
if (fn(pArray[i], pivotValue) < 0) {
swap(pArray, i, storeIndex);
storeIndex++;
}
}
swap(pArray, storeIndex, right);
return storeIndex;
}
const swap = (sArray, i = 0, j = 0) => {
let temp = sArray[i];
sArray[i] = sArray[j];
sArray[j] = temp;
}
// call quicksort with initial left and right indices
quickSort(array, 0, length(array) - 1);
return array;
}
Here’s an example of using sort
:
// Example usage:
const unsorted = [3, 2, 1, 4, 5];
const sorted = sort(unsorted, (a, b) => a - b);
console.log(sorted); // [1, 2, 3, 4, 5]
toLocalString
Next, let’s move on to the toLocalString
function. The toLocalString
function returns a string representing the elements of an array. It converts each element of the array to a string using the toLocaleString
method of that element and then concatenates the resulting strings with a comma separator.
The toLocaleString
function of each element is used to ensure that each element is represented as a string in a locale-specific format. This means that numbers, dates, and other objects that can be represented differently in different locales will be formatted appropriately based on the user’s locale.
The toLocaleString
method of an array can take two optional arguments: locales
and options
. The locales
argument specifies the locale or locales to use for formatting the array elements. The options
argument is an object that can contain various formatting options, such as style
for specifying whether to format numbers as currency or percentages.
Here’s how you can implement the toLocalString
function:
/**
* @name toLocalString
* @function
*
* @param {Array|Object} array the array to reverse
* @param {Number} len the len of the input array
* @param {Array} stringArray the result of the slice operation
* @param {String} separator the number of items
*
* @description Create the string representing the elements of the input array
*
* @return {String} The string representing the elements of an array
*
*/
const toLocalString = (array = [], len = length(array), stringArray = [], separator = new Intl.NumberFormat().format(1.1).charAt(1)) => {
if(!isArray(array)) throw new TypeError(`${array} must be an array`);
for (let i = 0; i < len; i++) {
if (array[i] === null || array[i] === undefined) {
push(stringArray,'');
} else {
push(stringArray, array[i].toLocaleString());
}
if(isArray(array[i])) toLocalString(array[i], len, stringArray, separator);
}
return join(stringArray, separator + ' ');
}
Here is an example of how to use toLocaleString
on an array of numbers:
const numbers = [12345.67, 8910.11, 123.45];
const formattedNumbers = toLocaleString(numbers, 'en-US', { style: 'currency', currency: 'USD' });
console.log(formattedNumbers); // "$12,345.67, $8,910.11, $123.45"
values
Next, let’s move on to the values
function. The values
function returns a new array iterator object that contains the values of an array. This method does not modify the original array.
The returned iterator object can be used to iterate over the values in the array using a for...of
loop or the next
method. The iterator object returns each value of the array in the order they appear in the array.
Here’s how you can implement the valus
function:
/**
* @name values
* @function
*
* @param {Array|Object} array the input array
* @param {Number} index the len of the input array
* @description Gets the values of the input array
*
* @return {Iterator} The string representing values of the array
*
*/
const values = (array = [], index = 0) => {
if(!isArray(array)) throw new TypeError(`${array} must be an array`);
const iterator = {
next: function() {
if (index < length(array)) {
return { value: array[index++], done: false };
} else {
return { done: true };
}
}
};
return iterator;
}
Here is an example of how to use the values
function on an array:
const fruits = ['apple', 'banana', 'cherry'];
const iterator = values(fruits);
console.log(iterator.next().value); // "apple"
console.log(iterator.next().value); // "banana"
console.log(iterator.next().value); // "cherry"
The values
function can be used in combination with other array iterator functions we saw earlier in this post, such as entries
and key
, to iterate over arrays in different ways.
unshift
Next, let’s move on to the unshift
function. The unshift
function adds one or more elements to the beginning of an array and returns the new length of the array.
The unshift
function modifies the original array by adding elements to the beginning of it. It does not create a new array. If no elements are provided to be added to the array, unshift
will simply return the length of the array.
Here’s how you can implement the unshift
function:
/**
* @name values
* @function
*
* @param {Array|Object} array the input array
* @description Unshift the input array
* @return {Array} The unshifted array
*
*/
const unshift = (array = []) => {
if(!isArray(array)) throw new TypeError(`${array} must be an array`);
const originalLength = length(array);
const newLength = originalLength + length(items);
for (let i = newLength - 1; i >= length(items); i--) {
arr[i] = arr[i - length(items)];
}
for (let i = 0; i < length(items); i++) {
array[i] = items[i];
}
return newLength;
}
Here is an example of how to use the unshift
method on an array:
const array = [1, 2, 3];
const length = unshift(array, 4, 5);
console.log(array); // [4, 5, 1, 2, 3]
console.log(length); // 5
The unshift
function can be useful when you want to add elements to the beginning of an array without modifying the original order of the elements. It can also be used to create a new array by adding elements to the beginning of an empty array.
Bonus: Using Some Functional Programming Tricks
Let’s create ademethodize
function that will allow us to create any of the functions we already created effortlessly. Here is an implementation of ourdemthodize
function:Â
/**
* @name demethodize
* @function
*
* @param {Function|Object} fn the function to bind to object method
*
* @description plucks off a method from ANY object and makes that method a completely independent standalone reusable function.
*
* For instance, if I wanted to make Array.prototype.map method an independent standalone reusable function, I would do something like this: const myArrayMap = pluckOff(Array.prototype.map). Then I would use it like this:
*
* const array = [1,2,3,4,5]; const result = myArrayMap(array, x => x * 2); result = [2,4,6,8,10]
*
* @return {Function|Object} fn.bind(...args)(), the completely independent standalone reusable function
*
*/
const demethodize = (fn = () => {}) => (...args)=> fn.bind(...args)();
The
demethodize
function takes a method functionfn
as its input parameter.It returns a new function that accepts any number of arguments
(...args)
.This new function creates a bound function by calling
fn.bind(...args)
. Thebind()
method creates a new function with the same body as the originalfn
function, but with itsthis
value bound to the object passed as the first argument. In this case,...args
represents the object that the methodfn
function would normally be called on.The new bound function is immediately called with no arguments
()
using the parentheses at the end of the line, and its return value is returned by the outer function.
Our demethodize
 function allows you to “demethodize” a method function so that it can be called separately from an object context. It does this by creating a bound function using fn.bind(...args)
and immediately calling it with no arguments ()
. The return value of the bound function is then returned by the outer function.
Let us now use demethodize
 function to re-create some of the Javascript functions we already created from scratch without using any of the Javascript built-in array methods.Â
Here is how to use the demethodize
function to create any of the javascript built-in array functions. To avoid repeating ourselves too much in this example we will use our demethodize
 to re-create only 3 functions (or methods): the forEach
, the map
, and the reduce
functions.
Let’s start with re-creating the demethodize
 function or method:
const forEach = demethodize(Array.prototype.forEach);
// now we can use our new forEach function
const array = [1,2,3,4,5,6,7];
forEach(array, (element, index, array) => console.log(element));
/* Output:
1
2
3
4
5
6
7
*/
Next, let’s start re-creating the map
 function or method:
const map = demethodize(Array.prototype.map);
// now we can use our new forEach function
const array = [1,2,3,4,5,6,7];
const tenTime = map(array, (element, index, array) => 10 * element);
console.log(tenTime)
//Output: [10,20,30,40,50,60,70]
Finally, let’s start re-creating the reduce
 function or method:
const reduce = demethodize(Array.prototype.reduce);
// now we can use our new forEach function
const array = [1,2,3,4,5,6,7];
const sum = reduce(array, (x, y) => x + y);
console.log(sum)
//Output: 28
Taking Ourdemethodize
function a little further.
You may have noticed that creating functions with our demethodize
function can become quite repetitive. For each function we create, we have to use it repeatedly to create all the variations we need. This can quickly become tiresome if we need to create many functions. However, there’s a more efficient way to do this. What if we could create a single function that allows us to generate all of the JavaScript built-in array methods, without having to use our function multiple times? This would save us time and make our code more concise.Â
That is exactly what we will do now: create a single function that allows us to generate all the javascript built-in array methods we already created without having to use our demethodize
function multiple times. Let’s call this function demethodizeConstruct
. Here is an implementation:Â
/**
* @name demethodizeConstruct
* @function
*
* @param {Function|Object} Source The object to demethodize
* @param {Function|Object} fn the function to apply to the source object
* @param {Function|Object} Destination The object to methodify
*
* @description Methodifies a destination object with all the methods on the prototype of the source object
*
* @return {Function|Object} The methodified object
*
*/
const demethodizeConstruct = (Source = {}, fn = () => {}, Destination = {}) => {
for(let method of Object.getOwnPropertyNames(Source.prototype)){
Destination[method] = fn(Source.prototype[method])
}
return Destination;
}
The
demethodizeConstruct
function takes three parameters: theSource
constructor function whose prototype methods need to be demethodized, thefn
function to apply to the theSource
constructor and theDestination
object where the demethodized functions will be added.It loops through all the prototype methods of the
Source
constructor function using afor..of
loop and theObject.getOwnPropertyNames
method.For each prototype method, it creates a new function using the
fn
function, passing in the method as thefn
parameter and an empty object{}
as thethisArg
parameter.It adds the new demethodized function to the
Destination
object with the same method name.The
Destination
object with the demethodized functions added to it is returned.
Our demethodizeConstruct
 function allows you to demethodize all the prototype methods of a constructor function and add them to a target object. It does this by looping through all the prototype methods of the Source
constructor function, using the demethodize
function to create a new demethodized function for each method, and adding the new demethodized function to the Destination
object. The Destination
object with the demethodized functions added to it is then returned.
Here is an example of how to use the demethodizeConstruct
method on an array:
const arrayFns = demethodizeConstruct(Array, demethodize);
// you could well use const {reduce } = demethodizeConstruct(Array, demethodize)
const {reduce} = arrayFns; //arrayFns object now has all the array methods as functions!
// now we can use our new forEach function
const array = [1,2,3,4,5,6,7];
const sum = reduce(array, (x, y) => x + y);
console.log(sum);
// //Output: 28
Final Thoughts
Writing your own JavaScript array methods can be a rewarding and educational experience. By understanding the underlying logic and algorithms used in the built-in array methods, you can create your own customized versions that suit your specific needs. Although it may seem daunting at first, with a little bit of practice and experimentation, you’ll soon be able to write efficient and effective array methods that can be used in your own projects.
It’s worth noting that while it’s certainly possible to write your own array methods without using any of the built-in JavaScript array methods, doing so may not always be the most practical approach. In many cases, the built-in methods are already highly optimized and efficient and may be more suitable for performance-critical applications. However, for learning purposes or for situations where you need highly specific behavior that is not available in the built-in methods, writing your own array methods can be a valuable tool in your JavaScript toolbox.
Overall, the key takeaway is to understand the principles behind JavaScript arrays and their methods and to use that knowledge to create your own customized solutions as needed. By doing so, you’ll be well on your way to becoming a more skilled and knowledgeable JavaScript developer.
Responses