가오리의 코딩일기

8장 함수형 프로그래밍, map, reduce, filter 본문

HTML+CSS+JavaScript/DeepDive

8장 함수형 프로그래밍, map, reduce, filter

류경혜 2022. 8. 2. 21:30

: 하나의 프로그래밍 패러다임으로 정의되는 일련의 코딩 접근 방식

→ 클로저, 스칼라, 하스켈, 자바스크립트, 코틀린, 파이썬 등이 있다

 

 

 

🧩 순수함수(Pure function)

→ 동일한 입력에는 항상 같은 값을 반환해야 하는 함수

→ 함수의 실행이 프로그램의 실행에 영향을 미치지 않아야 하는 함수

→ 함수 내부에서 인자의 값을 변경하거나 프로그램 상태를 변경하는 side effect가 없는 것

→ 프로그램의 변화 없이 입력 값에 대한 겨로가를 예상할 수 있어 테스트가 용이하다

let num = 1;
function add(a){
	return a + num;
}
// 전역으로 선언된 num을 참조하기 때문에 순수함수가 아니다
function add(a,b){
	return a+b;
}
// add()가 프로그램 실행에 영향을 미치지 않고 입력 값에 대해서만 값의 변환이 있으므로 순수함수

 

 

 

 

🧩 비상태, 불변성(stateless, immutability)

→ 함수형 프로그래밍에서의 데이터는 변하지 않는 불변성을 유지해야 한다

→ 데이터의 변경이 필요한 경우 원본 데이터의 복사본을 만들어서 복사본의 일부를 변경하고 변경한 복사본을 사용해 작업을 진행한다

let animal = { name: "gaori", age: "5" };

function increaseAge(animal) {
  animal.age = animal.age + 1;
  return animal;
}
// increaseAge()에서 전역으로 선언된 animal의 age 속성 변경 -> 불변성 만족X

// 비상태, 불변성 만족
const animal = { name: "gaori", age: "5" };

function increaseAge(animal) {
  return { ...animal, age: animal.age + 1 };
}

 

 

 

 

🧩 선언형 함수

→ 명령형 프로그래밍은 어떻게 풀어내는지(how to solve)에 집중

→ 선언형 프로그래밍은 무엇을 풀어내는지(what to solve)에 집중

→ 함수형 프로그래밍에서는 if, switch, for 등 명령문을 사용하지 않고 함수형 코드로 사용해야 한다

let numbers = [1, 2, 3];
// multiply(): for문을 사용해서 배열의 각 요소에 multiplier 곱해주는 명령형 프로그래밍
function multiply(numbers, multiplier) {
    for (let i = 0; i < numbers.length; i++) {
        numbers[i] = numbes[i] * multiplier;
    }
}
// 선언형 프로그래밍
function multiply(number, multiplier) {
    return number.map((num) => num * multiplier);
}

 

 

 

 

🧩 1급 객체와 고차함수(Fist-class, Higher-order functions)

→ 함수형 프로그래밍에서는 함수가 1급 객체가 된다

🔗 1급 객체 특징

더보기

→ 변수나 데이터 구조 안에 담을 수 있다

→ 파라미터로 전달할 수 있다

→ 반환값으로 사용할 수 있다

→ 할당에 사용된 이름과 관계없이 고유한 구별이 가능하다

→ 동적으로 프로퍼티 할당이 가능하다

const addTwo = (num) => num + 2;
const multiplyTwo = (num) => num * 2;
const transform = (numbers) => numbers.map(addTwo).map(multiplyTwo);

console.log(transform([1, 2, 3, 4])); // [6, 8, 10, 12]

🔗 고차 함수 특징

더보기

→ 함수를 인자로써 전달 할 수 있어야 한다

→ 함수의 반환값으로 또 다른 함수를 사용할 수 있다

const addInform = (name) => (age) => age + name;
const jongmin = addInform("종민");

console.log(jongmin("96")); // 96종민

 

 

 

 

🧩 array.map(callbackFunction(currentValue, index, array), thisArg)

: 기존의 배열을 callbackFunction에 의해 새 배열을 만드는 함수

→ 기존의 배열이 변하지 않는다

→ currentValue: 배열 내 현재 값

→ index: 배열 내 현재 값의 인덱스

→ array: 현재 배열

→ thisArg: callbackFunction 내에서 this로 사용될 값

→ 기존 배열에 값의 2배를 한 배열

let numbers = [1,2,3,4,5,6,7,8,9];
let newNumbers1= numbers.map(number => number *2);

let newNumbers2 = numbers.map(function(number){
	return number *2;
});

function multiplyTwo(number){
	return number *2;
}
let newNumber3 = number.map(multiplyTwo);
console.log(newNumbers1); // [2, 4, 6, 8, 10, 12, 14, 16, 18]
console.log(newNumbers2); // [2, 4, 6, 8, 10, 12, 14, 16, 18]
console.log(newNumbers3); // [2, 4, 6, 8, 10, 12, 14, 16, 18]

→ object 타입의 변수가 있는데 여기서 이름만 추출할 때 map()을 이용할 수 있다

let students = [
	{id:1, name: 'ryukyung'},
	{id:2, name: 'gaori'},
	{id:3, name: 'akoh'},
]
let names = students.map(student => stduent.name);
console.log(names); // ['ryukyung', 'gaori', 'akoh']

 

 

 

 

🧩 arr.reduce(callback[, initialValue])

: 배열의 각 요소에 대해 주어진 reducer 함수를 실행하고 하나의 결과값만 반환한다

→ 누산기가 포함되어 있기 때문에 배열의 각 요소에 대해 함수를 실행하고 누적된 값을 출력할 때 용이하다

→ callback: 배열의 각 요소에 대해 실행할 함수, 4가지 인수를 받는다

→ accumulator: 콜백의 반환값을 누적

→ currentValue: 처리할 현재 요소

→ currentIndex: 처리할 현재 요소의 인덱스, initialValue를 제공한 경우0, 아니면 1부터 시작

→ array: reduce()를 호출한 배열

→ initialValue: callback의 최초 호출에서 첫 번째 인수에 제공하는 값, 초기값 없으면 첫 번째 요소를 사용

→ 모든 배열의 합 구하기

const arr = [1,2,3,4,5];
const result1 = arr.reduce((acc, cur, idx) => { return acc += cur;}, 0);
const result2 = arr.reduce(function(acc, cur, idx){ 
	return acc += cur;
}, 10);
console.log(result1); // 15 = 0+1+2+3+4+5
console.log(result2)l // 25 = 10+1+2+3+4+5

 

 

 

 

🧩 arr.filter(callback(element[, index[,array]])[, thisArg])

: 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환한다

→ element: 요소값

→ index: 요소의 인덱스

→ array: 사용되는 배열 객체

→ thisArg: filter에서 사용될 this 값, 선택적으로 사용됨(undefined)

→ 기존 배열에서 짝수만 추출

const numbers = [1,2,3,4,5,6,7,8,9,10];
const evenNumbers1 = numbers.filter(num => {
	return num % 2 ===0;
});
const evenNumbers2 = numbers.filter((num) => num % 2 === 0 )
console.log(evenNumbers1); // [2,4,6,8,10]
console.log(evenNumbers2); // [2,4,6,8,10]

 

참고 블로그 : https://jongminfire.dev/%ED%95%A8%EC%88%98%ED%98%95-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EC%9D%B4%EB%9E%80

 

함수형 프로그래밍이란?

jongminfire.dev