Skip to content

Instantly share code, notes, and snippets.

@schan90
Last active August 21, 2017 22:25
Show Gist options
  • Save schan90/ffa8e0ebffabc3868f14427ad9a90635 to your computer and use it in GitHub Desktop.
Save schan90/ffa8e0ebffabc3868f14427ad9a90635 to your computer and use it in GitHub Desktop.
functional JS
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];
};
// 컬렉션 중심 프로그래밍의 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') );
// 컬렉션 중심 프로그래밍의 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);
// 컬렉션 중심 프로그래밍의 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;
}
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);
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');
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;
}
let [start, end] = [this.start, this.end];
function _is_object(obj) {
return typeof obj == 'object' && !!obj;
}
function _keys(obj) {
return _is_object(obj) ? Object.keys(obj) : [];
}
var _length = _get('length');
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