쏙쏙 들어오는 함수형 코딩 - #6

박상우·2023년 8월 16일
0
post-thumbnail

카피-온-라이트 원칙 3가지

  1. 복사본 만들기
  2. 복사본 변경하기
  3. 복사본 리턴하기

현재 카피-온-라이트의 경우 내부 데이터를 수정하지 않았고, 정보를 리턴하고 있기 때문에 읽기에 해당하는 동작을 수행한다.

//before
function remove_item_by_name(cart, name) {
	var idx = null;
	for (var i = 0; i < cart.length; i++) {
		idx = i;
	}
	if (idx !== null)
		cart.splice(idx, 1);
}

// after
function remove_item_by_name(cart, name) {
	var new_cart = cart.slice();
	var idx = null;
	for (var i = 0; i < new_cart.length; i++) {
		if (new_cart[i].name === name)
			idx = i;
	}
	if (idx !== null)
		new_cart.splice(idx, 1);

	return new_cart;
}

카피-온-라이트 모듈을 만들어두면 객체나 배열을 읽거나 쓰기에 편리하다.

⭐️ 배열 기능

//앞에 값 추가 -> .unshift(el)
var array = [1 ,2, 3, 4];
array.unshift(10)
console.log(array) // [ 10, 1, 2, 3, 4 ];

// 앞에 값 삭제 -> .shift()
var array = [1 ,2, 3, 4];
array.shift()
console.log(array) // [ 2, 3, 4 ];

연습문제 solve (p.120)

// before
var mailing_list = [];

function add_connect(email) {
	mailing_list.push(email);
}

function submit_form_handler(event) {
	var form = event.target;
	var email = form.elements['email'].value;
	add_connect(email);
}

// after
var mailing_list = [];

function add_connect(mail_list, email) {
	const new_mail_list = mail_list.slice();

	new_mail_list.push(email);
	
	return new_mail_list;
}

function submit_form_handler(event) {
	var form = event.target;
	var email = form.elements['email'].value;

	mailing_list = add_connect(mailing_list, email);
}

쓰기와 읽기를 함께하는동작

  1. 읽기와 쓰기 함수를 분리한다.
  2. 함수에서 값을 두 개(읽기에 해당하는 결과 값, 쓰기 후 결과값) 리턴한다.

연습문제 solve

//before
var a = [1, 2, 3, 4]
var b = a.pop();
console.log(b);
console.log(a);

//after
// 1. 읽기 함수와 쓰기 함수로 분리하기
function first_element(array) {
	return array[0];
}

function drop_first(array) {
	const array_copy = array.slice();
	array_copy.shift();
}

// 2. 값 두 개를 리턴하는 함수로 만들기
function shift(array) {
	var array_copy = array.slice();
	var first = array_copy.shift();
	
	return {
		first: first,
		array: array_copy
	}
}

연습문제 solve

// push 함수를 카피-온-라이트 버전으로 만들기
function push( array,elem) {
	const array_copy = array.slice();
	array_copy.push(elem);

	return array_copy;
}
// before
// 위 push 함수를 사용해서 리팩토링
function add_contact(mailing_list, email) {
	var list_copy = mailing_list.slice();
	list_copy.push(email);
	return list_copy;
}

// after
function add_contact(mailing_list, email) {
	const pushed_mailing_list = push(mailing_list, email);
	return pushed_mailing_list;
}

연습문제 solve

// 배열 항목 설정 함수를 카피-온-라이트 방식으로 제작
function arraySet(array, idx, value) {
	const copy_array = array.slice();
	copy_array[idx] = value;
	return copy_array;
}

불변 구조를 읽는 것은 계산이다.

변경 가능한 데이터를 읽는 것 ⇒ 액션

변경 불가능한 데이터를 읽는 것 ⇒ 계산

⇒ 데이터 구조를 불변형으로 바꾸면 코드내 계산은 늘어나고 액션을 줄일 수 있다.

시간에 따라 변하는 변수는 따로 두기

액션을 최소화 하기 위해 불변성 있는 데이터만 사용한다면 시간에 따라 변하는 값을 표현하기 힘들다. 그래서 전역변수에 새로운 값을 할당함으로서 시간에 따라 변하는 값을 표현할 수 있다.

불변 구조의 속도

불변 구조는 배열을 복사한다. 이는 메모리를 보다 많이 사용하고 느리다고 볼 수 있다. 하지만 언제든 최적화 가능하고, 언어별 가비지 콜랙터의 선응에 따라 더 개선된 속도로 사용할 수 있으며, 그리고 특정 함수형 프로그래밍 언어에서는 이를 빠르게 구현할 수 있는 구현체가 존재한다. 그리고 무엇보다 그렇게 많은 양을, 자주 복사하지 않는다.

객체의 카피-온-라이트

// before
function setPrice(item, price){
	item.price = price;
}

// after
function setPrice(item, price) {
	const item_copy = Object.assign({}, item);
	item_copy.price = new_price;
	
	return item_copy;
}

연습문제 solve

//  객체에 값을 설정하는 함수를 카피-온-라이트로 만들기
function objectSet(object, key, value) {
	const object_copy = Object.assign({}, object);
	object_copy[key] = value;
	
	return object_copy;
}
// objectSet 함수로 setPrice 고치기
// before
function setPrice(item, new_price) {
	const item_copy = Object.assign({}, item);
	item_copy.price = new_price;
	
	return item_copy;
}

// after
function setPrice(item, new_price) {
	return objectSet(item, 'price', new_price);
}
// 제품 개수 설정하는 함수(setQuantity) 만들기
function setQuantity(item, new_quantity){
	objectSet(item, 'quantity', new_quantity);
}
// 객체의 delete연산을 카피-온-라이트로 만들기
function objectDelete(object, key) {
	varr object_copy = Object.assign({}, object);
	delete object_copy[key];
	return object_copy;
}

중첩된 데이터 카피-온-라이트

중첩된 데이터의 경우 최상위 데이터를 복사하고, 쓰기를 하려고 하는 데이터를 한 번 더 복사한 후 덮어 쓰기 함으로서 중첩된 데이터의 읽기와 쓰기가 가능하다.

profile
나도 잘하고 싶다..!

0개의 댓글