중첩된 데이터에 함수형 도구 사용하기
July 9, 2024
쏙쏙들어오는 함수형 코딩
이번장에서 살펴볼 내용
- 해시 맵에 저장된 값을 다루기 위한 고차 함수를 만들기
- 중첩된 데이터를 고차 함수로 쉽게 다루는 방법을 알아보기
- 재귀를 이해하고 안전하게 재귀를 사용하는 방법 알아보기
- 깊이 중첩된 엔티티에 추상화벽을 적용해서 얻을수있는 장점을 이해하기
# 함수형 도구 update()
update() 함수는 객체를 다루는 함수형 도구다. update() 함수는 객체와, 변경할값이 어디있는지 알려주는 키값, 값을 변경하는 함수가 필요하다.
var shirt = {name: 'shirt',price: 13,}fucntion incrementShirtPrice(object, field) {return update(object, field, (v) => v+1)}incrementShirtPrice(shirt , 'price');function update(object, key , callback) {var value = object[key];var newValue = callback(value);var newObject = objectSet(object, key, newValue)return newObject;}
간단한 객체는 이렇게 처리 할 수 있다. 하지만 중첩된 객체라면 어떻게 해야할까?
var shirt = {name: 'shirt',price: 13,options: {color: 'blue',size: 3 // 이 property를 변경해야함}}function incrementShirtPrice(item) {return update(item, 'options', options => {return update(options, 'size', size => {return size + 1;})})}
위에서 주어진 객체보다 중첩이 훨씬 더 많이 된 객체의 property를 변경하는거라면??
function incrementShirtPrice(item) {return update(item, 'options', options => {return update(options, 'size', options1 => {return update(options1, 'a', options2 => {return update(options2, 'b', options3 => {// ...})})})})}
한두번 중첩된거라면 상관없지만 복잡하고 많이 중첩된 객체를 수정하려면 위의 코드와 같이 많은 수고가 따른다. 이럴땐 이 책에선 중첩되는 구조에서 재귀함수를 사용할것을 권장하고있다.
재귀함수를 사용할때 주의 할 점
- 종료조건을 사용해야한다.
- 재귀 함수가 실행되면서 점점 종료조건에 가까워져야한다.
재귀함수를 사용하여 반복되는 코드를 줄여보자
var object = {shirt: {name: 'shirt',price: 13,options: {color: 'blue',size: 3}}}var copyObj = (obj) => Object.assign(obj, {});var updateField = (o, field, callback) => {const object = copyObj(o);object[field] = callback(object[field]);return object;};var update = (o, k, callback) => {// 중단점에 callback 실행if (k.length === 0) {return callback(o);}var object = copyObj(o);var keys = k.slice();// firstKey를 가져오는 동시에 배열의 맨앞요소 삭제var firstKey = keys.shift();return updateField(object, firstKey, (value) => {return update(value, keys, callback);});};var incrementSize = (object, keys) => {return update(object, keys, (value) => value + 1)}incrementSize(object, ['shirt', 'options', 'size'])
key값을 하나씩 앞에서 줄여나가면서 객체를 복사하다가 마지막요소에서만 callback을 통해서 property를 수정하고나서 객체를 만들고 리턴했다
이렇게 update함수를 만들어놓으면 얼마나 중첩이 되어있든 내가원하는 객체의 property를 간단하게 수정 할 수 있다.
함수형도구 라이브러리인 Lodash에도 update와 비슷하게 동작하는 함수가 있으니 한번 찾아보자 https://lodash.com/docs/4.17.15#update