Creating Custom Higher Order Functions (Functional programming edition)

Fun... Fun... Fun... wait for it. Functions :)

·

2 min read

Hey Folks,

In one of my previous articles I talked about how to create our custom higher-order functions(map, filter, reduce,...etc) to understand higher-order functions better. I think we did a pretty good job there. Now I want to rewrite all these 3 functions without mutating any internal state. I will use the functional programming style and recursive a lot. I will also share code samples at the end of the article. Without any further ado, let's start. Code will speak for itself :)

function filter(predicateFn,arr) {
    if(length(arr) === 0) {
        return [];
    }
    const firstElement = head(arr);
    const firstElementFilter = predicateFn(firstElement) ? [firstElement] : [];
    return concat(firstElementFilter, filter(predicateFn,tail(arr)));

}

function map(fn, array) {
  if(length(array) === 0) {
      return [];
  }
  const firstElement  = head(array);
  const firstElementMap = [fn(firstElement)];
  return concat(firstElementMap,map(fn,tail(array)));
}

function reduce(fn,arr,initialValue) {
    if(length(arr) === 0){
        return initialValue;
    }
    const initial = initialValue ?? head(arr);
    const newArr = isPresent(initialValue) ? arr : tail(arr);
    const newInitialValue = fn(initial,head(newArr));
    return reduce(fn,tail(newArr),newInitialValue);
}

function some(predicateFn, arr) {
    for (const value of arr) {
        if(predicateFn(value)){
            return true;
        }
    }
    return false;
}


function isPresent(val) {
    return val !== undefined && val !== null;
}

function length(arr) {
    return arr.length;
}
function head(arr) {
    if(length(arr) === 0){
        return;
    }
    return arr[0];
}

function tail(arr) {
    if(length(arr) === 0){
        return;
    }
    return arr.slice(1);
}

function concat(arr1,arr2) {
    return arr1.concat(arr2);
}

const double = n => n * 2;
const isEven = n => n % 2  === 0;

const isPrime= n => {
    if(n < 2){
        return false
    }
    const wholes = [2,3,5,7];
    const possibleFactors = filter(num => num <= Math.sqrt(n), wholes )
    return !some(num => n % num === 0, possibleFactors)
}


const fizzBuzz = n => {
      let result = ''
      result += 'fizz'.repeat(n % 3 === 0)
      result += 'buzz'.repeat(n % 5 === 0)
      return result || n;
}

const fizzBuzz2 = n => {
      const fizzed = n % 3 === 0 ? 'fizz' : '';
      const buzzed = n % 5 === 0 ? 'buzz' : '';
      return fizzed || buzzed ? fizzed + buzzed : n ;
}

const product = (num1,num2) => num1 * num2;
const sumOfTwo = (num1,num2) => num1 + num2;

const arr = Array(100).fill(0).map((_,i) => i + 1)
console.log('Primes:',filter(isPrime,arr))
console.log('FizzBuzz:',map(fizzBuzz2,arr))
console.log(reduce(sumOfTwo,arr,0))

As I said here are the code samples . Feel free to give any comments/feedback. Until next time Bye bye.

Did you find this article valuable?

Support Chety by becoming a sponsor. Any amount is appreciated!