ReasonJun

javascript : Built-in higher order functions (HoFs) 본문

Frontend/Javasciprt

javascript : Built-in higher order functions (HoFs)

ReasonJun 2023. 6. 8. 16:38
728x90

In JavaScript, Higher-Order Functions (HoFs) are functions that can take other functions as arguments or return functions as their results. HoFs are a fundamental concept in functional programming and enable powerful and flexible ways to work with functions.

Here are some key aspects and characteristics of Higher-Order Functions in JavaScript:

  1. Functions as Arguments:
    • HoFs can accept other functions as arguments, treating functions as values. This allows you to pass behavior or logic as a parameter to another function, enabling customization and reusability. These functions are commonly referred to as "callback functions" or "function arguments".
  2. Functions as Return Values:
    • HoFs can also generate and return functions dynamically. This means that a function can be created and returned by another function, allowing for the creation of specialized or partially applied functions. This technique is often used for currying, partial function application, and function composition.
  3. Function Composition:
    • HoFs enable function composition, which is the process of combining multiple functions to create a new function. This allows you to chain together multiple function calls, where the output of one function becomes the input of another. Function composition promotes modularity and code reuse.
  4. Encapsulating Behavior:
    • HoFs provide a way to encapsulate behavior or logic in a reusable function, making code more modular and easier to understand. By abstracting behavior into separate functions, you can separate concerns and create more maintainable and reusable code.
  5. Examples of Higher-Order Functions:
    • Several built-in JavaScript functions are HoFs, such as forEach, map, filter, reduce, sort, and addEventListener. These functions take other functions as arguments to define custom behavior and iterate over arrays or handle events.

Here's an example demonstrating the concept of Higher-Order Functions:

function greet(name) {
  console.log(`Hello, ${name}!`);
}

function twice(fn, value) {
  fn(value);
  fn(value);
}

twice(greet, 'John');
// Output:
// Hello, John!
// Hello, John!

In this example, the twice function is a Higher-Order Function that takes a function (fn) as an argument and invokes it twice with a given value ('John' in this case). The greet function is passed as an argument to twice, and it is called twice, resulting in the greeting message being printed twice.

 

Higher-Order Functions provide a powerful way to work with functions in JavaScript, allowing for flexibility, reusability, and code abstraction. They are widely used in functional programming paradigms and are an essential tool in creating elegant and modular code.

 

map

function getFullNames(arr) {
  return arr.map(function (person) {
      return `${person.firstName} ${person.lastName}`;
    });
}

let output = getFullNames([
  {
    firstName: 'Tim',
    lastName: 'Goldfish',
  },
]);
console.log(output); // --> ['Tim Goldfish']

output = getFullNames([
  {
    firstName: 'Adam',
    lastName: 'Smith',
  },
  {
    firstName: 'Jack',
    lastName: 'Black',
  },
  {
    firstName: 'Samuel',
    lastName: 'Jackson',
  },
]);
console.log(output); // --> ['Adam Smith', 'Jack Black', 'Samuel Jackson']

output = getFullNames([]);
console.log(output); // --> []

 

function square(number) {
  return number * number;
}

function getSquaredElementsAtProperty(obj, property) {
  let maybeArr = obj[property];
  
    if (Array.isArray(maybeArr) === false) {
      return [];
    }
  
    return maybeArr.map(square);
}

const obj = {
  key: [2, 1, 5],
};

let output = getSquaredElementsAtProperty(obj, 'key');
console.log(output); // --> [4, 1, 25]

reduce

function computeProductOfAllElements(arr) {
  return arr.reduce(function (acc, val) {
      return acc * val;
    }, 1);
}

let output = computeProductOfAllElements([2, 5, 6]);
console.log(output); // --> 60

 

function joinArrayOfArrays(arr) {
  const joinedArr = arr.reduce(function (acc, val) {
      return acc.concat(val);
    });
    return joinedArr;
}

let output = joinArrayOfArrays([
  [1, 4],
  [true, false],
  ['x', 'y'],
]);

console.log(output); // --> [1, 4, true, false, 'x', 'y']

filter / map / reduce

function studentReports(students) {
  const onlyFemales = students.filter(function (el) {
    return el.gender === 'female';
  });

  return onlyFemales.map(function (el) {
    const sum = el.grades.reduce(function (acc, cur) {
      return acc + cur;
    }, 0);
    const avg = sum / el.grades.length;

    el.grades = avg;
    return el;
  });
}

let studentList = [
  {
    name: 'Anna',
    gender: 'female',
    grades: [4.5, 3.5, 4],
  },
  {
    name: 'Dennis',
    gender: 'male',
    country: 'Germany',
    grades: [5, 1.5, 4],
  },
  {
    name: 'Martha',
    gender: 'female',
    grades: [5, 4, 4, 3],
  },
  {
    name: 'Brock',
    gender: 'male',
    grades: [4, 3, 2],
  },
];

let output = studentReports(studentList);

console.log(output); // -->
[
  { name: 'Anna', gender: 'female', grades: 4 },
  { name: 'Martha', gender: 'female', grades: 4 },
];

reduce / filter

function sumOfArraysInArray(arr) {
    const joinedArr = arr.reduce(function (acc, cur){
        return acc.concat(cur);
    });

    const onlyNumbers = joinedArr.filter(function(el){
        if(typeof el == typeof 1){
            return el;
        }
    })
    return onlyNumbers.reduce(function(acc, cur){
        return acc + cur
    }, 0)
}

    
  
  
  let output = sumOfArraysInArray([
    [1, 2],
    [undefined, 4, '5'],
    [9, 'hello'],
  ]);
  console.log(output); // --> 16

application

function removeElement(arr, discarder) {
  return arr.filter(function(num){
    if(num !== discarder){
      return true
    }
    else false
  })
}

let output = removeElement([1, 2, 3, 2, 1], 2);
console.log(output); // --> [1, 3, 1]
function filterOddLengthWords(words) {
  return words.filter(function(str){
    return str.length %2 !== 0;
  })
}
let output = filterOddLengthWords(['there', 'it', 'is', 'now']);
console.log(output); // --> ['there', "now']
function getIndex(arr, num) {
  return arr.filter(function(numArr){
    return num >= numArr;
  }).length
}
let output = getIndex([5, 4, 1, 3], 2);
console.log(output); // --> 1

output = getIndex([10, 5, 1, 3], 13);
console.log(output); // --> 4
function lessThan100(number) {
  // solution 1
  return number < 100;

  // solution 2
  // return typeof number === 'number' && number < 100;
}

function getElementsLessThan100AtProperty(obj, property) {
  const maybeArr = obj[property];
  if (Array.isArray(maybeArr)) {
    // solution 1
    return maybeArr.filter(function (el) {
      return typeof el === 'number' && lessThan100(el);
    });
  }

  return [];
}
const obj = {
  key: [1000, 20, 50, 500],
};

let output = getElementsLessThan100AtProperty(obj, 'key');
console.log(output); // --> [20, 50]
728x90
Comments