Last active
August 21, 2017 22:25
-
-
Save schan90/ffa8e0ebffabc3868f14427ad9a90635 to your computer and use it in GitHub Desktop.
functional JS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function _curry(fn) { | |
return function(a, b) { | |
return arguments.length == 2 ? fn(a, b) : function(b) { return fn(a, b); }; | |
} | |
} | |
function _curryr(fn) { | |
return function(a, b) { | |
return arguments.length == 2 ? fn(a, b) : function(b) { return fn(b, a); }; | |
} | |
} | |
var _get = _curryr(function(obj, key) { | |
return obj == null ? undefined : obj[key]; | |
}); | |
function _filter(list, predi) { | |
var new_list = []; | |
_each(list, function(val) { | |
if (predi(val)) new_list.push(val); | |
}); | |
return new_list; | |
} | |
function _map(list, mapper) { | |
var new_list = []; | |
_each(list, function(val, key) { | |
new_list.push(mapper(val, key)); | |
}); | |
return new_list; | |
} | |
function _is_object(obj) { | |
return typeof obj == 'object' && !!obj; | |
} | |
function _keys(obj) { | |
return _is_object(obj) ? Object.keys(obj) : []; | |
} | |
var _length = _get('length'); | |
function _each(list, iter) { | |
var keys = _keys(list); | |
for (var i = 0, len = keys.length; i < len; i++) { | |
iter(list[keys[i]], keys[i]); | |
} | |
return list; | |
} | |
var _map = _curryr(_map), | |
_each = _curryr(_each), | |
_filter = _curryr(_filter); | |
var _pairs = _map(function (val, key) { return [key, val]; }); | |
var slice = Array.prototype.slice; | |
function _rest(list, num) { | |
return slice.call(list, num || 1); | |
} | |
function _reduce(list, iter, memo) { | |
if (arguments.length == 2) { | |
memo = list[0]; | |
list = _rest(list); | |
} | |
_each(list, function(val) { | |
memo = iter(memo, val); | |
}); | |
return memo; | |
} | |
function _pipe() { | |
var fns = arguments; | |
return function(arg) { | |
return _reduce(fns, function(arg, fn) { | |
return fn(arg); | |
}, arg); | |
} | |
} | |
function _go(arg) { | |
var fns = _rest(arguments); | |
return _pipe.apply(null, fns)(arg); | |
} | |
var _values = _map(_identity); | |
function _identity(val) { | |
return val; | |
} | |
var _pluck = _curryr(function(data, key) { | |
return _map(data, _get(key)); | |
}); | |
function _negate(func) { | |
return function(val) { | |
return !func(val); | |
} | |
} | |
var _reject = _curryr(function(data, predi) { | |
return _filter(data, _negate(predi)); | |
}); | |
var _compact = _filter(_identity); | |
var _find = _curryr(function(list, predi) { | |
var keys = _keys(list); | |
for (var i = 0, len = keys.length; i < len; i++) { | |
var val = list[keys[i]]; | |
if (predi(val)) return val; | |
} | |
}); | |
var _find_index = _curryr(function(list, predi) { | |
var keys = _keys(list); | |
for (var i = 0, len = keys.length; i < len; i++) { | |
if (predi(list[keys[i]])) return i; | |
} | |
return -1; | |
}); | |
function _some(data, predi) { | |
return _find_index(data, predi || _identity) != -1; | |
} | |
function _every(data, predi) { | |
return _find_index(data, _negate(predi || _identity)) == -1; | |
} | |
function _push(obj, key, val) { | |
(obj[key] = obj[key] || []).push(val); | |
return obj; | |
} | |
var _group_by = _curryr(function(data, iter) { | |
return _reduce(data, function(grouped, val) { | |
return _push(grouped, iter(val), val); | |
}, {}); | |
}); | |
var _inc = function(count, key) { | |
count[key] ? count[key]++ : count[key] = 1; | |
return count; | |
}; | |
var _count_by = _curryr(function(data, iter) { | |
return _reduce(data, function(count, val) { | |
return _inc(count, iter(val)); | |
}, {}); | |
}); | |
var _head = function(list) { | |
return list[0]; | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 컬렉션 중심 프로그래밍의 4가지 유형과 함수 | |
// 1. 수집하기 - map > values, pluck 등 | |
// 2. 거르기 - filter > reject, compact, without 등 | |
// 3. 찾아내기 - find > some, every 등 | |
// 4. 접기 - reduce > min, max, group_by, count_by | |
########### | |
function _is_object(obj) { | |
return typeof obj == 'object' && !!obj; | |
} | |
function _keys(obj) { | |
return _is_object(obj) ? Object.keys(obj) : []; | |
} | |
function _each(list, iter) { | |
var keys = _keys(list); | |
for (var i = 0, len = keys.length; i < len; i++) { | |
iter(list[keys[i]], keys[i]); | |
} | |
return list; | |
} | |
function _map(list, mapper) { | |
var new_list = []; | |
_each(list, function(val, key) { | |
new_list.push(mapper(val, key)); | |
}); | |
return new_list; | |
} | |
function _filter(list, predi) { | |
var new_list = []; | |
_each(list, function(val) { | |
if (predi(val)) new_list.push(val); | |
}); | |
return new_list; | |
} | |
function _curry(fn) { | |
return function(a, b) { | |
return arguments.length == 2 ? fn(a, b) : function(b) { return fn(a, b); }; | |
} | |
} | |
function _curryr(fn) { | |
return function(a, b) { | |
return arguments.length == 2 ? fn(a, b) : function(b) { return fn(b, a); }; | |
} | |
} | |
//var _map = _curryr(_map), | |
// _each = _curryr(_each), | |
// _filter = _curryr(_filter); | |
var [_map,_each,_filter] = [_curryr(_map),_curryr(_each),_curryr(_filter)]; | |
############# | |
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-1 values | |
function _identity(val) {return val;} | |
var _values = _map(_identity); | |
console.log(_values(users[0])); | |
#1-2 pluck | |
var _pluck = _curryr(function(data, key) { | |
return _map(data, _get(key)); | |
}); | |
console.log( _pluck(users, 'age') ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 컬렉션 중심 프로그래밍의 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 } | |
]; | |
##### | |
#2-1 reject | |
function _negate(func) { | |
return function(val) { | |
return !func(val); | |
}} | |
var _reject = _curryr(function(data, predi) { | |
return _filter(data, _negate(predi)); | |
}); | |
#2-2 | |
var _compact = _filter(_identity); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 컬렉션 중심 프로그래밍의 4가지 유형과 함수 | |
// 1. 수집하기 - map > values, pluck 등 | |
// 2. 거르기 - filter > reject, compact, without 등 | |
// 3. 찾아내기 - find > some, every 등 | |
// 4. 접기 - reduce > min, max, group_by, count_by | |
###### | |
var _find = _curryr(function(list, predi) { | |
var keys = _keys(list); | |
for (var i = 0, len = keys.length; i < len; i++) { | |
var val = list[keys[i]]; | |
if (predi(val)) return val; | |
} | |
}); | |
var _find_index = _curryr(function(list, predi) { | |
var keys = _keys(list); | |
for (var i = 0, len = keys.length; i < len; i++) { | |
if (predi(list[keys[i]])) return i; | |
} | |
return -1; | |
}); | |
function _some(data, predi) { | |
return _find_index(data, predi || _identity) != -1; | |
} | |
function _every(data, predi) { | |
return _find_index(data, _negate(predi || _identity)) == -1; | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 } | |
]; | |
//var users2 = { | |
// 36: [{ id: 10, name: 'ID', age: 36 }], | |
// 32: [{ id: 20, name: 'BJ', age: 32 }, { id: 30, name: 'JM', age: 32 }], | |
// 27: [], | |
// ... | |
//} | |
############# | |
// 1. min, max, min_by, max_by | |
function _min(data) { | |
return _reduce(data, function(a, b) { | |
return a < b ? a : b; | |
}); | |
} | |
function _max(data) { | |
return _reduce(data, function(a, b) { | |
return a > b ? a : b; | |
}); | |
} | |
function _min_by(data, iter) { | |
return _reduce(data, function(a, b) { | |
return iter(a) < iter(b) ? a : b; | |
}); | |
} | |
function _max_by(data, iter) { | |
return _reduce(data, function(a, b) { | |
return iter(a) > iter(b) ? a : b; | |
}); | |
} | |
var _min_by = _curryr(_min_by), | |
_max_by = _curryr(_max_by); | |
console.log( | |
_min_by([1, 2, 4, 10, 5, -4], Math.abs) | |
); | |
console.log( | |
_min([1, 2, 4, 10, 5, -4]) | |
); | |
console.log( | |
_max([1, 2, 4, 10, 5, -4]) | |
); | |
console.log( | |
_max_by([1, 2, 4, 10, 5, -4, -11], Math.abs) | |
); | |
console.log( | |
_min_by(users, function(user) { | |
return user.age; | |
}) | |
); | |
_go(users, | |
_filter(user => user.age >= 30), | |
_map(_get('age')), | |
_min, | |
console.log); | |
_go(users, | |
_reject(user => user.age >= 30), | |
_max_by(_get('age')), | |
_get('name'), | |
console.log); | |
############### | |
// 2. group_by, push | |
function _push(obj, key, val) { | |
(obj[key] = obj[key] || []).push(val); | |
return obj; | |
} | |
var _group_by = _curryr(function(data, iter) { | |
return _reduce(data, function(grouped, val) { | |
return _push(grouped, iter(val), val); | |
}, {}); | |
}); | |
var _head = function(list) { | |
return list[0]; | |
}; | |
#### | |
_go(users, | |
_group_by(_get('age')), | |
console.log); | |
_go(users, | |
_group_by(function(user) { | |
return user.age - user.age % 10; | |
}), | |
console.log); | |
_go(users, | |
_group_by(function(user) { | |
return user.name[0]; | |
}), | |
console.log); | |
_go(users, | |
_group_by(_pipe(_get('name'), _head)), | |
console.log); | |
##### | |
// 3. count_by, inc | |
var _inc = function(count, key) { | |
count[key] ? count[key]++ : count[key] = 1; | |
return count; | |
}; | |
var _count_by = _curryr(function(data, iter) { | |
return _reduce(data, function(count, val) { | |
return _inc(count, iter(val)); | |
}, {}); | |
}); | |
console.log( | |
_count_by(users, function(user) { | |
return user.age - user.age % 10; | |
}) | |
); | |
_go(users, | |
_count_by(function(user) { | |
return user.name[0]; | |
}), | |
console.log); | |
console.log( _pairs(users[0]) ); | |
ar f1 = _pipe( | |
_count_by(function(user) { return user.age - user.age % 10; }), | |
_map((count, key) => `<li>${key}대는 ${count}명 입니다.</li>`), | |
list => '<ul>' + list.join('') + '</ul>', | |
document.write.bind(document)); | |
_go(users, _reject(user => user.age < 20), f1); | |
_go(users, _filter(user => user.age < 20), f1); | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const p3 = (a)=>(b)=>(c)=>a+b+c ; | |
p3(1)(2)(3); | |
#### | |
function _curry(fn) { | |
return function(a, b) { | |
return arguments.length == 2 ? fn(a, b) : function(b) { return fn(a, b); }; | |
} | |
} | |
function _curryr(fn) { | |
return function(a, b) { | |
return arguments.length == 2 ? fn(a, b) : function(b) { return fn(b, a); }; | |
} | |
} | |
var _get = _curryr(function(obj, key) { | |
return obj == null ? undefined : obj[key]; | |
}); | |
var _length = _get('length'); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function _is_object(obj) { | |
return typeof obj == 'object' && !!obj; | |
} | |
function _keys(obj) { | |
return _is_object(obj) ? Object.keys(obj) : []; | |
} | |
function _each(list, iter) { | |
var keys = _keys(list); | |
for (var i = 0, len = keys.length; i < len; i++) { | |
iter(list[keys[i]], keys[i]); | |
} | |
return list; | |
} | |
function _map(list, mapper) { | |
var new_list = []; | |
_each(list, function(val, key) { | |
new_list.push(mapper(val, key)); | |
}); | |
return new_list; | |
} | |
function _filter(list, predi) { | |
var new_list = []; | |
_each(list, function(val) { | |
if (predi(val)) new_list.push(val); | |
}); | |
return new_list; | |
} | |
function _curry(fn) { | |
return function(a, b) { | |
return arguments.length == 2 ? fn(a, b) : function(b) { return fn(a, b); }; | |
} | |
} | |
function _curryr(fn) { | |
return function(a, b) { | |
return arguments.length == 2 ? fn(a, b) : function(b) { return fn(b, a); }; | |
} | |
} | |
var _map = _curryr(_map), | |
_each = _curryr(_each), | |
_filter = _curryr(_filter); | |
### | |
function _reduce(list, iter, memo) { | |
if (arguments.length == 2) { | |
memo = list[0]; | |
list = _rest(list); | |
} | |
_each(list, function(val) { | |
memo = iter(memo, val); | |
}); | |
return memo; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let [start, end] = [this.start, this.end]; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function _is_object(obj) { | |
return typeof obj == 'object' && !!obj; | |
} | |
function _keys(obj) { | |
return _is_object(obj) ? Object.keys(obj) : []; | |
} | |
var _length = _get('length'); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function _is_object(obj) { | |
return typeof obj == 'object' && !!obj; | |
} | |
function _keys(obj) { | |
return _is_object(obj) ? Object.keys(obj) : []; | |
} | |
function _each(list, iter) { | |
var keys = _keys(list); | |
for (var i = 0, len = keys.length; i < len; i++) { | |
iter(list[keys[i]], keys[i]); | |
} | |
return list; | |
} | |
var slice = Array.prototype.slice; | |
function _rest(list, num) { | |
return slice.call(list, num || 1); | |
} | |
### | |
function _reduce(list, iter, memo) { | |
if (arguments.length == 2) { | |
memo = list[0]; | |
list = _rest(list); | |
} | |
_each(list, function(val) { | |
memo = iter(memo, val); | |
}); | |
return memo; | |
} | |
### | |
function _pipe() { | |
var fns = arguments; | |
return function(arg) { | |
return _reduce(fns, function(arg, fn) { | |
return fn(arg); | |
}, arg); | |
} | |
} | |
function _go(arg) { | |
var fns = _rest(arguments); | |
return _pipe.apply(null, fns)(arg); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment