Last active
October 31, 2015 20:24
-
-
Save gaogao-9/df618056df14db8ca277 to your computer and use it in GitHub Desktop.
Array.prototypeをSymbolで汚染する夢が見たかった…(gao_functional.jsが、3つのファイルをconcatしたソースコードです) 現状Firefoxのみ動作可能です
This file contains 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 _ = GaoFunctional(); | |
var input = "114514"; | |
var res = input[_.count](); | |
console.log(res); // 6 | |
var input2 = [1,1,4,5,1,4]; | |
var res2 = input2[_.count]((x)=>x===1); | |
console.log(res2); // 3 | |
var input3 = {id:2,name:"gao",age:18}; | |
var res3 = input3[_.count](); | |
console.log(res3); // 3 | |
var input4 = {id:2,name:"gao",age:18}; | |
var res4 = input4[_.count.withKey]((v,k)=>((k==="id")||(v===18))); | |
console.log(res4); // 2 | |
console.log("gaogao_9"[_.map](c=>c.charCodeAt())); // [103,97,111,103,97,111,95,57] | |
console.log([1,2,3,4,5][_.reduceRight.withIndex]((x,y,i)=>(x+i),0)); //10 | |
console.log([1,2,3,4,5][_.some](x=>x===2)); // true | |
console.log("ZIP"[_.zip]("でくれ",(x,y)=>[x,y])); // [["Z","で"],["I","く"],["P","れ"]] |
This file contains 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 GaoFunctional; | |
!function(){ | |
"use strict"; | |
var methodSymbols = {}; | |
var methodCallbacks = {}; | |
var optionCallbacks = {}; | |
var methodArgumentsLengths = {}; | |
var optionArgumentsLengths = {}; | |
var gaoFunctionalSymbol = Symbol("GaoFunctional"); | |
function addMethod(methodName,callback,useArgumentsLength){ | |
methodSymbols[methodName] = Object(Symbol(methodName)); | |
methodCallbacks[methodName] = callback; | |
methodArgumentsLengths[methodName] = useArgumentsLength || 0; | |
registerPrototypeMethod(methodSymbols[methodName],methodName,[]); | |
var optionList = Object.keys(optionCallbacks); | |
addOptionTree(methodSymbols[methodName],methodName,optionList,[]); | |
} | |
function addOption(optionName,callback,useArgumentsLength){ | |
optionCallbacks[optionName] = callback; | |
optionArgumentsLengths[optionName] = useArgumentsLength || 0; | |
var optionList = Object.keys(optionCallbacks); | |
for(var methodName of Object.keys(methodSymbols)){ | |
addOptionTree(methodSymbols[methodName],methodName,optionList,[]); | |
} | |
} | |
function addOptionTree(target,methodName,optionRestList,optionList){ | |
for(var [optionIndex,optionName] of optionRestList.entries()){ | |
var nextOptionRestList = optionRestList.concat(); | |
var nextOptionList = optionList.concat(nextOptionRestList.splice(optionIndex,1)); | |
if(!(optionName in target)){ | |
target[optionName] = Object(Symbol(nextOptionList.join("."))); | |
registerPrototypeMethod(target[optionName],methodName,nextOptionList); | |
} | |
addOptionTree(target[optionName],methodName,nextOptionRestList,nextOptionList); | |
} | |
} | |
function registerPrototypeMethod(target,methodName,optionList){ | |
const notHasIteratorList = [Object] | |
.map((obj)=>[obj,makeMethod(methodName,methodCallbacks[methodName],optionList)]); | |
const hasIteratorList = [String,Map,Set,Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array] | |
.map((obj)=>[obj,makeMethod(methodName,methodCallbacks[methodName],optionList)]); | |
Array.prototype.push.apply(notHasIteratorList,hasIteratorList); | |
notHasIteratorList.forEach((x)=>{ | |
Object.defineProperty(x[0].prototype,target,{ | |
value: x[1], | |
writable : false, | |
enumerable : false, | |
configurable: false | |
}); | |
}); | |
} | |
function makeMethod(methodName,methodGenerator,optionList){ | |
return function(callback,...options){ | |
var [keys,values] = getEntries(this); | |
// 長さが0の時は空配列を返して終了 | |
if(!values.length) return []; | |
const methodArguments = []; | |
for(var i=0,iLen=methodArgumentsLengths[methodName];i<iLen;++i){ | |
if(options[i] && options[i][gaoFunctionalSymbol]){ | |
methodArguments.push(undefined); | |
} | |
else{ | |
methodArguments.push(options[i]); | |
} | |
} | |
const methodItr = methodGenerator(callback,...methodArguments,values,keys,options,gaoFunctionalSymbol); | |
var methodItrRes = methodItr.next(); | |
const optionGenerators = []; | |
const optionItrList = []; | |
var optionItr,optionItrRes; | |
var beforeValue; | |
for(var optionName of optionList){ | |
optionGenerators.push(optionCallbacks[optionName]); | |
} | |
var optionArgumentsPos = methodArgumentsLengths[methodName]; | |
for(var [optionIndex,optionName] of optionList.entries()){ | |
var optionGenerator = optionGenerators[optionIndex]; | |
var optionArguments = []; | |
for(var i=optionArgumentsPos,iLen=optionArgumentsLengths[optionName];i<iLen;++i){ | |
if(options[i] && options[i][gaoFunctionalSymbol]){ | |
optionArguments.push(undefined); | |
} | |
else{ | |
optionArguments.push(options[i]); | |
} | |
} | |
optionArgumentsPos += iLen; | |
optionItr = optionGenerator(callback,...optionArguments,values,keys,options,gaoFunctionalSymbol); | |
optionItrList.push(optionItr); | |
optionItrRes = optionItr.next(); | |
} | |
var index = methodItrRes.value; | |
while(!methodItrRes.done){ | |
var args = []; | |
for(var [optionIndex,optionName] of optionList.entries()){ | |
optionItrRes = optionItrList[optionIndex].next(index); | |
if(optionItrRes.value !== undefined) args.push(optionItrRes.value); | |
} | |
methodItrRes = methodItr.next(args); | |
index = methodItrRes.value; | |
} | |
return methodItrRes.value; | |
}; | |
} | |
function getEntries(target){ | |
var keys,values; | |
if(target[Symbol.iterator]){ | |
keys = (target.keys) ? Array.from(target.keys()) : Object.keys(target); | |
values = (target.values) ? Array.from(target.values()) : target; | |
} | |
else{ | |
[keys,values] = getObjectEntries(target); | |
} | |
return [keys,values]; | |
} | |
function getObjectEntries(obj){ | |
var keys = Object.keys(obj); | |
var values = []; | |
for(var key of keys){ | |
values.push(obj[key]); | |
} | |
return [keys,values]; | |
} | |
methodSymbols[gaoFunctionalSymbol] = true; | |
GaoFunctional = function(){ return methodSymbols; }; | |
GaoFunctional.addMethod = addMethod; | |
GaoFunctional.addOption = addOption; | |
GaoFunctional.getEntries = getEntries; | |
}(); | |
!function(){ | |
"use strict"; | |
GaoFunctional.addMethod("each",eachGenerator); | |
GaoFunctional.addMethod("map",mapGenerator); | |
GaoFunctional.addMethod("groupBy",groupByGenerator); | |
GaoFunctional.addMethod("reduce",reduceGenerator,1); | |
GaoFunctional.addMethod("reduceRight",reduceRightGenerator,1); | |
GaoFunctional.addMethod("zip",zipGenerator,1); | |
GaoFunctional.addMethod("sort",sortGenerator); | |
GaoFunctional.addMethod("filter",filterGenerator); | |
GaoFunctional.addMethod("reject",rejectGenerator); | |
GaoFunctional.addMethod("find",findGenerator); | |
GaoFunctional.addMethod("findIndex",findIndexGenerator); | |
GaoFunctional.addMethod("indexOf",alias(findIndexGenerator)); | |
GaoFunctional.addMethod("every",everyGenerator); | |
GaoFunctional.addMethod("some",someGenerator); | |
GaoFunctional.addMethod("all",alias(everyGenerator)); | |
GaoFunctional.addMethod("any",alias(someGenerator)); | |
GaoFunctional.addMethod("one",oneGenerator); | |
GaoFunctional.addMethod("none",noneGenerator); | |
GaoFunctional.addMethod("skip",skipGenerator); | |
GaoFunctional.addMethod("take",takeGenerator); | |
GaoFunctional.addMethod("takeWhile",takeWhileGenerator); | |
GaoFunctional.addMethod("count",countGenerator); | |
GaoFunctional.addMethod("min",minGenerator); | |
GaoFunctional.addMethod("max",maxGenerator); | |
GaoFunctional.addMethod("toObject",toObjectGenerator,1); | |
function alias(generator){ | |
return generator; | |
} | |
function* eachGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
var args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
callback(arr[i], ...args); | |
args = yield i+1; | |
} | |
} | |
function* mapGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
const output = []; | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
output.push(value); | |
args = yield i+1; | |
} | |
return output; | |
} | |
function* groupByGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
const output = {}; | |
var key, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
key = callback(arr[i], ...args); | |
output[key] = output[key] || []; | |
output[key].push(arr[i]); | |
args = yield i+1; | |
} | |
return output; | |
} | |
function* reduceGenerator(callback,initValue,arr,keys,options,gaoFunctionalSymbol){ | |
if(arr.length===0) return initValue; | |
var cnt = 0; | |
var value, args = yield cnt; | |
if(initValue !== undefined){ | |
value = initValue; | |
} | |
else if(arr.length===1) return arr[0]; | |
else{ | |
value = arr[cnt++]; | |
args = yield cnt; | |
} | |
for(var i=cnt,iLen=arr.length;i<iLen;++i){ | |
value = callback(value, arr[i], ...args); | |
if(iLen-1-i){ | |
args = yield i+1; | |
} | |
} | |
return value; | |
} | |
function* reduceRightGenerator(callback,initValue,arr,keys,options,gaoFunctionalSymbol){ | |
if(arr.length===0) return initValue; | |
var cnt = arr.length-1; | |
var value, args = yield cnt; | |
if(initValue !== undefined){ | |
value = initValue; | |
} | |
else if(arr.length===1) return arr[0]; | |
else{ | |
value = arr[cnt--]; | |
args = yield cnt; | |
} | |
for(var i=cnt+1;i--;){ | |
value = callback(value, arr[i], ...args); | |
if(i){ | |
args = yield i-1; | |
} | |
} | |
return value; | |
} | |
function* zipGenerator(arr2,callback,arr,keys,options,gaoFunctionalSymbol){ | |
const output = []; | |
var [arr2Keys,arr2Values] = GaoFunctional.getEntries(arr2); | |
var value, args = yield 0; | |
for(var i=0,iLen=(Math.min(arr.length,arr2Values.length)||0);i<iLen;++i){ | |
value = callback(arr[i],arr2Values[i], ...args); | |
output.push(value); | |
args = yield i+1; | |
} | |
return output; | |
} | |
function* sortGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
const output = arr.concat(); | |
output.sort(callback); | |
return output; | |
} | |
function* everyGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
if(!value) return false; | |
args = yield i+1; | |
} | |
return true; | |
} | |
function* filterGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
const output = []; | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
if(value) output.push(arr[i]); | |
args = yield i+1; | |
} | |
return output; | |
} | |
function* rejectGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
const output = []; | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
if(!value) output.push(arr[i]); | |
args = yield i+1; | |
} | |
return output; | |
} | |
function* findGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
if(typeof(callback) !== "function") return arr[arr.indexOf(callback)]; | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
if(value) return arr[i]; | |
args = yield i+1; | |
} | |
return undefined; | |
} | |
function* findIndexGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
if(typeof(callback) !== "function") return arr.indexOf(callback); | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
if(value) return i; | |
args = yield i+1; | |
} | |
return undefined; | |
} | |
function* someGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
if(value) return true; | |
args = yield i+1; | |
} | |
return false; | |
} | |
function* oneGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
var output = false; | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
if(value){ | |
if(!output) output = true; | |
else return false; | |
} | |
args = yield i+1; | |
} | |
return false; | |
} | |
function* noneGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
var output = false; | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
if(value){ | |
if(!output) output = true; | |
else return false; | |
} | |
args = yield i+1; | |
} | |
return false; | |
} | |
function* skipGenerator(num,arr,keys,options,gaoFunctionalSymbol){ | |
return arr.slice(num); | |
} | |
function* takeGenerator(num,arr,keys,options,gaoFunctionalSymbol){ | |
return arr.slice(0,num); | |
} | |
function* takeWhileGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
const output = []; | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
if(!value) break; | |
output.push(args[0]); | |
args = yield i+1; | |
} | |
return output; | |
} | |
function* countGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
if(!callback) return arr.length; | |
var output = 0; | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
if(value) ++output; | |
args = yield i+1; | |
} | |
return output; | |
} | |
function* minGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
if(!callback) return Math.min.apply(null,arr); | |
const firstValue = Symbol("firstValue"); | |
var output = firstValue; | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
if(isNaN(value)){ | |
output = null; | |
break; | |
} | |
if((output===firstValue)||(output>value)){ | |
output = value; | |
} | |
args = yield i+1; | |
} | |
return output; | |
} | |
function* maxGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
if(!callback) return Math.max.apply(null,arr); | |
const firstValue = Symbol("firstValue"); | |
var output = firstValue; | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
if(isNaN(value)){ | |
output = null; | |
break; | |
} | |
if((output===firstValue)||(output<value)){ | |
output = value; | |
} | |
args = yield i+1; | |
} | |
return output; | |
} | |
function* toObjectGenerator(keyCallback,valueCallback,arr,keys,options,gaoFunctionalSymbol){ | |
const output = {}; | |
var key, value; | |
var args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
key = keyCallback(arr[i], ...args); | |
value = valueCallback(arr[i], ...args); | |
output[key] = res; | |
args = yield i+1; | |
} | |
return output; | |
} | |
}(); | |
!function(){ | |
"use strict"; | |
GaoFunctional.addOption("withIndex",withIndexGenerator); | |
GaoFunctional.addOption("withKey",withKeyGenerator); | |
GaoFunctional.addOption("withObject",withObjectGenerator,1); | |
function* withIndexGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
var iteratorIndex = yield; | |
while(true){ | |
iteratorIndex = yield iteratorIndex; | |
} | |
} | |
function* withKeyGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
var iteratorIndex = yield; | |
while(true){ | |
iteratorIndex = yield keys[iteratorIndex]; | |
} | |
} | |
function* withObjectGenerator(callback,obj,arr,keys,options,gaoFunctionalSymbol){ | |
if(obj && obj[gaoFunctionalSymbol]) obj = undefined; | |
yield; | |
while(true){ | |
yield obj; | |
} | |
} | |
}(); |
This file contains 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 GaoFunctional; | |
!function(){ | |
"use strict"; | |
var methodSymbols = {}; | |
var methodCallbacks = {}; | |
var optionCallbacks = {}; | |
var methodArgumentsLengths = {}; | |
var optionArgumentsLengths = {}; | |
var gaoFunctionalSymbol = Symbol("GaoFunctional"); | |
function addMethod(methodName,callback,useArgumentsLength){ | |
methodSymbols[methodName] = Object(Symbol(methodName)); | |
methodCallbacks[methodName] = callback; | |
methodArgumentsLengths[methodName] = useArgumentsLength || 0; | |
registerPrototypeMethod(methodSymbols[methodName],methodName,[]); | |
var optionList = Object.keys(optionCallbacks); | |
addOptionTree(methodSymbols[methodName],methodName,optionList,[]); | |
} | |
function addOption(optionName,callback,useArgumentsLength){ | |
optionCallbacks[optionName] = callback; | |
optionArgumentsLengths[optionName] = useArgumentsLength || 0; | |
var optionList = Object.keys(optionCallbacks); | |
for(var methodName of Object.keys(methodSymbols)){ | |
addOptionTree(methodSymbols[methodName],methodName,optionList,[]); | |
} | |
} | |
function addOptionTree(target,methodName,optionRestList,optionList){ | |
for(var [optionIndex,optionName] of optionRestList.entries()){ | |
var nextOptionRestList = optionRestList.concat(); | |
var nextOptionList = optionList.concat(nextOptionRestList.splice(optionIndex,1)); | |
if(!(optionName in target)){ | |
target[optionName] = Object(Symbol(nextOptionList.join("."))); | |
registerPrototypeMethod(target[optionName],methodName,nextOptionList); | |
} | |
addOptionTree(target[optionName],methodName,nextOptionRestList,nextOptionList); | |
} | |
} | |
function registerPrototypeMethod(target,methodName,optionList){ | |
const notHasIteratorList = [Object] | |
.map((obj)=>[obj,makeMethod(methodName,methodCallbacks[methodName],optionList)]); | |
const hasIteratorList = [String,Map,Set,Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array] | |
.map((obj)=>[obj,makeMethod(methodName,methodCallbacks[methodName],optionList)]); | |
Array.prototype.push.apply(notHasIteratorList,hasIteratorList); | |
notHasIteratorList.forEach((x)=>{ | |
Object.defineProperty(x[0].prototype,target,{ | |
value: x[1], | |
writable : false, | |
enumerable : false, | |
configurable: false | |
}); | |
}); | |
} | |
function makeMethod(methodName,methodGenerator,optionList){ | |
return function(callback,...options){ | |
var [keys,values] = getEntries(this); | |
// 長さが0の時は空配列を返して終了 | |
if(!values.length) return []; | |
const methodArguments = []; | |
for(var i=0,iLen=methodArgumentsLengths[methodName];i<iLen;++i){ | |
if(options[i] && options[i][gaoFunctionalSymbol]){ | |
methodArguments.push(undefined); | |
} | |
else{ | |
methodArguments.push(options[i]); | |
} | |
} | |
const methodItr = methodGenerator(callback,...methodArguments,values,keys,options,gaoFunctionalSymbol); | |
var methodItrRes = methodItr.next(); | |
const optionGenerators = []; | |
const optionItrList = []; | |
var optionItr,optionItrRes; | |
var beforeValue; | |
for(var optionName of optionList){ | |
optionGenerators.push(optionCallbacks[optionName]); | |
} | |
var optionArgumentsPos = methodArgumentsLengths[methodName]; | |
for(var [optionIndex,optionName] of optionList.entries()){ | |
var optionGenerator = optionGenerators[optionIndex]; | |
var optionArguments = []; | |
for(var i=optionArgumentsPos,iLen=optionArgumentsLengths[optionName];i<iLen;++i){ | |
if(options[i] && options[i][gaoFunctionalSymbol]){ | |
optionArguments.push(undefined); | |
} | |
else{ | |
optionArguments.push(options[i]); | |
} | |
} | |
optionArgumentsPos += iLen; | |
optionItr = optionGenerator(callback,...optionArguments,values,keys,options,gaoFunctionalSymbol); | |
optionItrList.push(optionItr); | |
optionItrRes = optionItr.next(); | |
} | |
var index = methodItrRes.value; | |
while(!methodItrRes.done){ | |
var args = []; | |
for(var [optionIndex,optionName] of optionList.entries()){ | |
optionItrRes = optionItrList[optionIndex].next(index); | |
if(optionItrRes.value !== undefined) args.push(optionItrRes.value); | |
} | |
methodItrRes = methodItr.next(args); | |
index = methodItrRes.value; | |
} | |
return methodItrRes.value; | |
}; | |
} | |
function getEntries(target){ | |
var keys,values; | |
if(target[Symbol.iterator]){ | |
keys = (target.keys) ? Array.from(target.keys()) : Object.keys(target); | |
values = (target.values) ? Array.from(target.values()) : target; | |
} | |
else{ | |
[keys,values] = getObjectEntries(target); | |
} | |
return [keys,values]; | |
} | |
function getObjectEntries(obj){ | |
var keys = Object.keys(obj); | |
var values = []; | |
for(var key of keys){ | |
values.push(obj[key]); | |
} | |
return [keys,values]; | |
} | |
methodSymbols[gaoFunctionalSymbol] = true; | |
GaoFunctional = function(){ return methodSymbols; }; | |
GaoFunctional.addMethod = addMethod; | |
GaoFunctional.addOption = addOption; | |
GaoFunctional.getEntries = getEntries; | |
}(); |
This file contains 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(){ | |
"use strict"; | |
GaoFunctional.addMethod("each",eachGenerator); | |
GaoFunctional.addMethod("map",mapGenerator); | |
GaoFunctional.addMethod("groupBy",groupByGenerator); | |
GaoFunctional.addMethod("reduce",reduceGenerator,1); | |
GaoFunctional.addMethod("reduceRight",reduceRightGenerator,1); | |
GaoFunctional.addMethod("zip",zipGenerator,1); | |
GaoFunctional.addMethod("sort",sortGenerator); | |
GaoFunctional.addMethod("filter",filterGenerator); | |
GaoFunctional.addMethod("reject",rejectGenerator); | |
GaoFunctional.addMethod("find",findGenerator); | |
GaoFunctional.addMethod("findIndex",findIndexGenerator); | |
GaoFunctional.addMethod("indexOf",alias(findIndexGenerator)); | |
GaoFunctional.addMethod("every",everyGenerator); | |
GaoFunctional.addMethod("some",someGenerator); | |
GaoFunctional.addMethod("all",alias(everyGenerator)); | |
GaoFunctional.addMethod("any",alias(someGenerator)); | |
GaoFunctional.addMethod("one",oneGenerator); | |
GaoFunctional.addMethod("none",noneGenerator); | |
GaoFunctional.addMethod("skip",skipGenerator); | |
GaoFunctional.addMethod("take",takeGenerator); | |
GaoFunctional.addMethod("takeWhile",takeWhileGenerator); | |
GaoFunctional.addMethod("count",countGenerator); | |
GaoFunctional.addMethod("min",minGenerator); | |
GaoFunctional.addMethod("max",maxGenerator); | |
GaoFunctional.addMethod("toObject",toObjectGenerator,1); | |
function alias(generator){ | |
return generator; | |
} | |
function* eachGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
var args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
callback(arr[i], ...args); | |
args = yield i+1; | |
} | |
} | |
function* mapGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
const output = []; | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
output.push(value); | |
args = yield i+1; | |
} | |
return output; | |
} | |
function* groupByGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
const output = {}; | |
var key, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
key = callback(arr[i], ...args); | |
output[key] = output[key] || []; | |
output[key].push(arr[i]); | |
args = yield i+1; | |
} | |
return output; | |
} | |
function* reduceGenerator(callback,initValue,arr,keys,options,gaoFunctionalSymbol){ | |
if(arr.length===0) return initValue; | |
var cnt = 0; | |
var value, args = yield cnt; | |
if(initValue !== undefined){ | |
value = initValue; | |
} | |
else if(arr.length===1) return arr[0]; | |
else{ | |
value = arr[cnt++]; | |
args = yield cnt; | |
} | |
for(var i=cnt,iLen=arr.length;i<iLen;++i){ | |
value = callback(value, arr[i], ...args); | |
if(iLen-1-i){ | |
args = yield i+1; | |
} | |
} | |
return value; | |
} | |
function* reduceRightGenerator(callback,initValue,arr,keys,options,gaoFunctionalSymbol){ | |
if(arr.length===0) return initValue; | |
var cnt = arr.length-1; | |
var value, args = yield cnt; | |
if(initValue !== undefined){ | |
value = initValue; | |
} | |
else if(arr.length===1) return arr[0]; | |
else{ | |
value = arr[cnt--]; | |
args = yield cnt; | |
} | |
for(var i=cnt+1;i--;){ | |
value = callback(value, arr[i], ...args); | |
if(i){ | |
args = yield i-1; | |
} | |
} | |
return value; | |
} | |
function* zipGenerator(arr2,callback,arr,keys,options,gaoFunctionalSymbol){ | |
const output = []; | |
var [arr2Keys,arr2Values] = GaoFunctional.getEntries(arr2); | |
var value, args = yield 0; | |
for(var i=0,iLen=(Math.min(arr.length,arr2Values.length)||0);i<iLen;++i){ | |
value = callback(arr[i],arr2Values[i], ...args); | |
output.push(value); | |
args = yield i+1; | |
} | |
return output; | |
} | |
function* sortGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
const output = arr.concat(); | |
output.sort(callback); | |
return output; | |
} | |
function* everyGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
if(!value) return false; | |
args = yield i+1; | |
} | |
return true; | |
} | |
function* filterGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
const output = []; | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
if(value) output.push(arr[i]); | |
args = yield i+1; | |
} | |
return output; | |
} | |
function* rejectGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
const output = []; | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
if(!value) output.push(arr[i]); | |
args = yield i+1; | |
} | |
return output; | |
} | |
function* findGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
if(typeof(callback) !== "function") return arr[arr.indexOf(callback)]; | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
if(value) return arr[i]; | |
args = yield i+1; | |
} | |
return undefined; | |
} | |
function* findIndexGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
if(typeof(callback) !== "function") return arr.indexOf(callback); | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
if(value) return i; | |
args = yield i+1; | |
} | |
return undefined; | |
} | |
function* someGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
if(value) return true; | |
args = yield i+1; | |
} | |
return false; | |
} | |
function* oneGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
var output = false; | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
if(value){ | |
if(!output) output = true; | |
else return false; | |
} | |
args = yield i+1; | |
} | |
return false; | |
} | |
function* noneGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
var output = false; | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
if(value){ | |
if(!output) output = true; | |
else return false; | |
} | |
args = yield i+1; | |
} | |
return false; | |
} | |
function* skipGenerator(num,arr,keys,options,gaoFunctionalSymbol){ | |
return arr.slice(num); | |
} | |
function* takeGenerator(num,arr,keys,options,gaoFunctionalSymbol){ | |
return arr.slice(0,num); | |
} | |
function* takeWhileGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
const output = []; | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
if(!value) break; | |
output.push(args[0]); | |
args = yield i+1; | |
} | |
return output; | |
} | |
function* countGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
if(!callback) return arr.length; | |
var output = 0; | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
if(value) ++output; | |
args = yield i+1; | |
} | |
return output; | |
} | |
function* minGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
if(!callback) return Math.min.apply(null,arr); | |
const firstValue = Symbol("firstValue"); | |
var output = firstValue; | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
if(isNaN(value)){ | |
output = null; | |
break; | |
} | |
if((output===firstValue)||(output>value)){ | |
output = value; | |
} | |
args = yield i+1; | |
} | |
return output; | |
} | |
function* maxGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
if(!callback) return Math.max.apply(null,arr); | |
const firstValue = Symbol("firstValue"); | |
var output = firstValue; | |
var value, args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
value = callback(arr[i], ...args); | |
if(isNaN(value)){ | |
output = null; | |
break; | |
} | |
if((output===firstValue)||(output<value)){ | |
output = value; | |
} | |
args = yield i+1; | |
} | |
return output; | |
} | |
function* toObjectGenerator(keyCallback,valueCallback,arr,keys,options,gaoFunctionalSymbol){ | |
const output = {}; | |
var key, value; | |
var args = yield 0; | |
for(var i=0,iLen=arr.length;i<iLen;++i){ | |
key = keyCallback(arr[i], ...args); | |
value = valueCallback(arr[i], ...args); | |
output[key] = res; | |
args = yield i+1; | |
} | |
return output; | |
} | |
}(); |
This file contains 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(){ | |
"use strict"; | |
GaoFunctional.addOption("withIndex",withIndexGenerator); | |
GaoFunctional.addOption("withKey",withKeyGenerator); | |
GaoFunctional.addOption("withObject",withObjectGenerator,1); | |
function* withIndexGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
var iteratorIndex = yield; | |
while(true){ | |
iteratorIndex = yield iteratorIndex; | |
} | |
} | |
function* withKeyGenerator(callback,arr,keys,options,gaoFunctionalSymbol){ | |
var iteratorIndex = yield; | |
while(true){ | |
iteratorIndex = yield keys[iteratorIndex]; | |
} | |
} | |
function* withObjectGenerator(callback,obj,arr,keys,options,gaoFunctionalSymbol){ | |
if(obj && obj[gaoFunctionalSymbol]) obj = undefined; | |
yield; | |
while(true){ | |
yield obj; | |
} | |
} | |
}(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment