ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 함수형 프로그래밍(ES5)-3.컬렉션 중심 프로그램 (1,2,3)
    카테고리 없음 2022. 4. 18. 21:52

    -컬렉션 중심 프로그래밍

    : 컬랙션을 잘 다루는 함수 세트들을 구성하는 식으로 프로그래밍해나가는걸 컬렉션 중심 프로그래밍이라고 함

     

    컬렉션 : 배열, 리스트와 같은 돌림직한 데이터를 다루는 것

    ex ) map, reduce, filter

     

     

    4가지 유형으로 나누면

    1. 수집하기 - map, values, pluck

    2. 거르기 - filter, reject, compact, without

    3. 찾아내기 - find, some, every

    4. 접기(축약) - reduce, min, max, group_by, count_by

     

    대표함수 : 각 유형의 모든 함수 중 추상화 레벨이 가장 높은 함수 => 대표함수로 각 유형의 특화함수를 만들 수 있다.

     

     

    -컬렉션 중심 프로그래밍의 유형별 함수 만들기

     

    var users = [
    	{ id: 10, name: 'ID', age: 36 },
        { id: 20, name: 'BJ', age: 32 },
        { id: 30, name: 'JM', age: 32 },
        { id: 40, name: 'PJ', age: 27 },
        { id: 50, name: 'HA', age: 25 },
        { id: 60, name: 'JE', age: 26 },
        { id: 70, name: 'JI', age: 31 },
        { id: 80, name: 'MP', age: 23 },
        { id: 90, name: 'FP', age: 13 } 
    ];

    1. 수집하기 - map -> values, pluck

     

    function _map(list, mapper) {
        const new_list = [];
        for (let i = 0; i < list.length; i++) {
            new_list.push(mapper(list[i]));
        }
        return new_list;
    }
    
    console.log(
    	_map(users, function(users) {
        	return users.name;
        })
    )
    
    결과 : (9) ["ID", "BJ", "JM", "PJ", "HA", "JE", "JI", "MP", "FP"]

    -> 내부 값 수집

     

    1-1 values 함수 : object의 값들을 꺼내는 함수 (배열인 경우 input, output이 같아 의미 없음)

    const object1 = {
      a: 'somestring',
      b: 42,
      c: false
    };
    
    console.log(Object.values(object1));
    // expected output: Array ["somestring", 42, false]
    
    //참조 https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/values

    -map으로 values 만들기

    function _values(data) {
    	return _map(data, function(val) {return val;});
    }
    
    console.log(users[0])
    
    //{id: 10, name: "ID", age:36}
    
    console.log(_values(users[0]))
    
    //{10, "ID", 36}
    
    console.log(_keys(users[0]))
    
    //{"id", "name", "age"}

     

    -_identity함수로 대체

    function _values(data) {
    	return _map(data, _identity)
    }
    
    function _identity(val) {
    	return val
    }

    1-2. pluck : 객체의 key 에 대한 값을 수집하는 함수 (간결함, 실용적!)

    _pluck(users, 'age');
    
    //[33, 22, 11, ...]
    function _pluck(data, key) {
      return _map(data, function(obj) {
        return obj[key];
      })
    }
    
    function __pluck(data, key) {
      return _map(data, _get(key));
    }
    console.log(_pluck(users, 'age'))
    
    //[36, 32, 32, 27, 25, 26, 31, 23, 13]

     

    2. 거르기 - filter -> reject, compact

    -filter : 조건에 true인 값만 꺼내기

    function _filter(list, predi) {
        const new_list = [];
        _each(list, function(val) {
            if (predi(val)) new_list.push(val);
        });
        return new_list;
    }
    console.log(
    	_filter(users, function(user) {
        	return user.age >30;
        })
    )

    2.1 reject : filter와 반대로 조건에 true인 값 제외시키는 함수

     

    function _reject(data, predi){
    	return _filter(data, function(val){
        		return !predi(val)
        })
    }

    - predi 부분 함수화

    function _negate(func){
        return function(val){   
            return !func(val);
        }
    }

    -간결해짐!

    function _reject(data, predi){
        return _filter(data, _negate(predi));
    }

     

    2.2 compact 함수 : 정의되지 않은 값 (null)이 없는 새 배열을 반환하는 함수

    var _filter = _curryr(_filter);
    
    var _compact = _filter(_identity);
    
    console.log(_compact([1, 2, 0, false, null, {}]));   
    
    // [ 1, 2, {} ]

    컬렉션을 다루는 다양하고 서로 다른 함수 세트를 다양하게 구성하는게 컬렉션 중심의 프로그래밍 목표!

     

    3. 찾아내기 - find : 배열에서 조건에 맞는 첫번째 값 리턴하는 함수 / find_index 조건에 맞는 첫번째 값 인덱스

    (filter는 조건과 맞는 모든 값 / find는 첫번째 값)

    3.1 find 함수 만들기

    function _find(list, predi) {
      var keys = _keys(list);
      for (var i = 0, len = keys.length; i < len; i++) {
        const val = list[keys[i]])
        if(predi(val)) return val;
      }
    }
    console.log(
      _find(users, function(user) {
        return user.age < 30;
      })
    )
    
    // {id: 40, name: "PJ", age: 27}
    
    console.log(
      _find(users, function(user) {
        return user.id == 20;
      })
    )

    find 함수는 filter와 달리 첫번째 값만 리턴하는 함수이기 때문에 원하는 값을 찾으면 배열을 빠져나올 수 있는 최적화가 특징!

     

    3.2 index_of

    function _find_index(list, predi) {
      var keys = _keys(list);
      for (var i = 0, len = keys.length; i < len; i++) {
        if(predi(list[keys[i]]))) return i;
      }
    }

    _get 함수 사용

    console.log(
      _get(_find(users, function(user) {
        return user.id == 50;
      }), 'name');
    );
    
    // HA

    _curryr 함수 사용

    var _find = _curryr(function(list, predi) {
      var keys = _keys(list);
      for (var i = 0, len = keys.length; i < len; i++) {
        const val = list[keys[i]])
        if(predi(val)) return val;
      }
    })
    
    
    _go(users,
      _find(function(user) { return user.id == 50; }),
      _get('name'),
      console.log
    )
    
    // HA

    3.3 some : 하나의 조건이라도 만족하면 true를 리턴

    _some([1, 2, 5, 10, 20], function(val) {
      return val > 10;
    });
    
    // true

    find_index함수로 만들기

    function _some(data, predi) {
    	return _find_index(data, predi) != -1
    }
    console.log(_some([1,2,5,10,20], function(val) {
    	return val > 20;
    }))
    
    //false
    
    console.log(_some([1,2,5,10,20], function(val) {
    	return val > 10;
    }))
    
    //true

    3.4 every : 모든 값이 조건에 만족해야 true를 리턴

    _every([1, 2, 5, 10, 20], function(val) {
      return val > 10;
    });
    
    // false
    function _every(data, predi) {
      return _find_index(data, _negate(predi)) == -1;
    }
    console.log(_every([1,2,5,10,20], function(val) {
    	return val > 20;
    }))
    
    //false
    
    console.log(_every([12,23,54,12,20], function(val) {
    	return val > 10;
    }))
    
    //true

    predi 없이 사용하기

    console.log(
    	_some([1,2,0,20],_identity)
    )
    
    //true
    
    console.log(
    	_some([null, false, 0],_identity)
    )
    
    //false

     

    function _some(data, predi) {
      return _find_index(data, _negate(predi || _identity)) == -1;
    }
    
    function _every(data, predi) {
      return _find_index(data, _negate(pred || _identity)) == -1;
    }

     

     

    console.log(
    	_some(users, function(user) {
        	return user.age < 20
        })
    )
    
    //true

     

    console.log(_some([1,2,5,10,20], function(val) { return val > 20;}))
                    //고차함수                 보조함수

    앞에 있는 고차함수를 고르고, 보조함수로 맵핑하면서 프로그래밍 하는것은 로직을 고르는 것과 같다!

    -> 로직을 조합해 나가는 방식으로 프로그래밍하기

Designed by Tistory.