New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

functools

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

functools - npm Package Compare versions

Comparing version 1.2.0 to 1.3.0

.npmignore

160

lib/functools.js
var functools = (function(undefined){
function isArray(el){
return Object.prototype.toString.call(el) == '[object Array]';
var slice = Array.prototype.slice;
function isArray(obj){
return Object.prototype.toString.call(obj) == '[object Array]';
}
function objectKeys(obj){
var keys = [], key;
for(key in obj){
keys.push( key );
}
return keys;
}
/**
* Function composition implementation
*/
*/
function compose(/* functions */){
var fns = Array.prototype.slice.call(arguments);
var fns = slice.call(arguments);
return function(initialValue){
return reduce(function(f,g){
return function(val){
return function(val){
return g(f(val));

@@ -21,4 +31,4 @@ };

compose.async = function compose_async(/* functions */){
var fns = Array.prototype.slice.call(arguments);
compose.async = function composeAsync(/* functions */){
var fns = slice.call(arguments);
return function(initialValue,callback){

@@ -41,3 +51,3 @@ (function(i,error,value){

* a list containing the result of applying each fn to the arguments.
*
*
* usage examples;

@@ -48,3 +58,3 @@ * juxt(Number, String, Array)(true) => [1, "true", [true]]

function juxt(/* functions */){
var fns = arguments.length > 1 || typeof arguments[0] != 'object' ? arguments : arguments[0];
var fns = arguments.length > 1 || typeof arguments[0] != 'object' ? slice.call(arguments) : arguments[0];

@@ -54,3 +64,3 @@ return function(){

return map(function(fn){
return fn.apply(undefined, args);
return fn.apply(undefined, args);
}, fns);

@@ -62,5 +72,6 @@ };

juxt.async = function(/* functions */){
var fns = arguments.length > 1 || typeof arguments[0] != 'object' ? arguments : arguments[0];
var fns = arguments.length > 1 || typeof arguments[0] != 'object' ? slice.call(arguments) : arguments[0];
return function(/* args, callback */){
var args = Array.prototype.slice.call(arguments, 0, arguments.length-1),
var args = slice.call(arguments, 0, arguments.length-1),
callback = arguments[arguments.length-1];

@@ -79,3 +90,3 @@

function curry(fn){
var args = Array.prototype.slice.call(arguments,1),
var args = slice.call(arguments,1),
len = fn.length;

@@ -91,4 +102,5 @@ return (function(){

*/
function each(fn,iterable){
for(var i = -1, len=iterable.length; ++i < len; ){
function each(fn, iterable){
var i, len;
for(i = -1, len=iterable.length; ++i < len; ){
fn(iterable[i],i,iterable);

@@ -99,6 +111,19 @@ };

each.async = function(fn, iterable, callback){
(function next(i, error){
if( error || i >= iterable.length ){
callback && callback(error);
return;
}
fn(iterable[i], i, iterable, partial(next, [i+1]));
}(0));
};
/**
* Apply 'fn' to every element of 'iterable', returning those elements for which fn returned a true value.
*/
function filter(fn,iterable){
function filter(fn, iterable){
var accumulation = [];

@@ -111,3 +136,3 @@ for(var i = -1, len=iterable.length; ++i < len; ){

filter.async = function filter_async(fn, iterable, callback){
filter.async = function filterAsync(fn, iterable, callback){
var accumulation = [];

@@ -126,3 +151,3 @@ (function(i,ptest){

})(0);
}
};

@@ -137,6 +162,6 @@ /**

clone = Array.prototype.slice.call(iterable, 0);
clone = slice.call(iterable, 0);
i = -1;
len = clone.length;
while(++i<len){

@@ -147,3 +172,3 @@ clone[i] = fn(clone[i], i, clone);

} else if(typeof iterable == 'object') {
clone = {};

@@ -160,11 +185,11 @@

map.async = function map_async(fn, iterable, callback){
map.async = function mapAsync(fn, iterable, callback){
var clone, iter, i, len, key, value,
list = isArray(iterable);
iter = list ? Array.prototype.slice.call(iterable) : Object.keys(iterable);
iter = list ? slice.call(iterable) : objectKeys(iterable);
clone = list ? iter : {};
(function next(i, error, rpl){
key = list ? i-1 : iter[i-1];

@@ -186,2 +211,62 @@ value = list ? clone[i] : iterable[ iter[i] ];

/*
* Return a memoized version of 'fn'
*/
function memoize(fn, hash){
var mem = {};
!hash && ( hash = function(n){ return n; });
return function memoizedFn(){
var key = hash.apply(undefined, arguments);
return mem.hasOwnProperty(key) ? mem[key] : ( mem[ key ] = fn.apply(undefined, arguments) );
};
}
memoize.async = function memoizeAsync(fn, hash){
var mem = {}, queues = {};
!hash && ( hash = function(n){ return n; });
return function memoizedAsyncFn(){
var args = slice.call(arguments),
key = hash.apply(undefined, args),
callback = args.pop();
if( key in mem ){
callback.apply(undefined, mem[ key ]);
return;
}
if( key in queues){
queues[key].push(callback);
return;
}
queues[key] = [callback];
args.push(function asyncMemoizeCallback(error/*, result */){
var args = arguments;
!error && ( mem[ key ] = args );
(function next(i){
if( i >= queues[key].length ){
delete queues[key];
return;
}
var cb = queues[ key ][i];
setTimeout(function(){
cb.apply(undefined, args);
}, 0);
next(i+1);
}(0));
});
fn.apply(undefined, args);
};
};
/**

@@ -193,3 +278,3 @@ * Return a new function which will call 'fn' with the positional arguments 'args'

return function(){
var args = Array.prototype.slice.call(initialArgs,0);
var args = slice.call(initialArgs,0);
Array.prototype.push.apply(args,arguments);

@@ -203,3 +288,3 @@ return fn.apply(ctx,args);

*/
function reduce(fn,iterable){
function reduce(fn, iterable){
var accumulator = iterable[0];

@@ -214,5 +299,5 @@

reduce.async = function reduce_async(fn,iterable,callback){
reduce.async = function reduceAsync(fn, iterable,callback){
(function(i, error, accumulator){
if(error || i>=iterable.length){

@@ -229,10 +314,11 @@ callback(error, accumulator);

return {
"compose":compose,
"curry":curry,
"each":each,
"filter":filter,
'juxt':juxt,
"map":map,
"partial":partial,
"reduce":reduce
"compose": compose,
"curry": curry,
"each": each,
"filter": filter,
'juxt': juxt,
"map": map,
"memoize": memoize,
"partial": partial,
"reduce": reduce
};

@@ -239,0 +325,0 @@

{
"name":"functools",
"version":"1.2.0",
"version":"1.3.0",
"description":"A minimal library of functional operations",

@@ -9,3 +9,10 @@ "author":"Azer Koculu <azer@kodfabrik.com>",

"main":"./lib/functools",
"repository": { "type":"git", "url" : "http://github.com/azer/functools.git" }
"repository": { "type":"git", "url" : "http://github.com/azer/functools.git" },
"devDependencies":{
"lowkick":"0.x",
"highkick":"1.x"
},
"scripts":{
"test":"./node_modules/.bin/highkick test/main.js"
}
}

@@ -60,3 +60,3 @@ functools is a JavaScript library for functional programming.

or
or

@@ -67,4 +67,33 @@ ```bash

# WHAT'S NEW?
09.06.2012
* each.async
* memoize
* memoize.async
06.06.2012
* IE6, IE7 and IE8 bugfixes
* better testing
# API
* [compose](#compose)
* [compose.async](#compose.async)
* [curry](#curry)
* [each](#each)
* [each.async](#each.async)
* [filter](#filter)
* [filter.async](#filter.async)
* [juxt](#juxt)
* [juxt.async](#juxt.async)
* [map](#map)
* [map.async](#map.async)
* [memoize](#memoize)
* [memoize.async](#memoize.async)
* [partial](#partial)
* [reduce](#reduce)
* [reduce.async](#reduce.async)
<a name="compose" />
## compose(*functions ...*)(*value*)

@@ -81,2 +110,3 @@

<a name="compose.async" />
## compose.async(*functions ...*)(*value*,*callback*)

@@ -100,3 +130,3 @@

```
<a name="curry" />
## curry(*function*, *args ...*)

@@ -115,32 +145,98 @@

<a name="each" />
## each(*function*,*iterable*)
## partial(*function*,*initial arguments*,*context *)
Call *function* once for each element in *iterable*.
Return a new function which will call *function* with the gathered arguments.
```javascript
each(function(el,ind,list){ console.assert( el == list[ind] ); }, [3, 1, 4]);
```
<a name="each.async" />
## each(*function*,*iterable*,*callback*)
Call async *function* once for each element in *iterable*, and *callback* after iteration.
```javascript
function testPartial(){
var args = reduce(function(x,y){ x+", "+y },arguments);
console.log("this:",this);
console.log("args:",args);
}
> function uploadFile(filename, index, files, callback){ console.log('Uploading ', filename); callback(); }
partial(testPartial, [3,14], 3.14159)(1,5,9);
> each.async(uploadFile, [ '/docs/intro', '/docs/body', '/docs/outro' ], function(error){
if(error){
console.log('Failed to upload files');
throw error;
}
console.log('All files has been uploaded successfully');
});
> Uploading /docs/intro
Uploading /docs/body
Uploading /docs/outro
All files has been uploaded successfully
```
The example code above will output:
<a name="filter" />
## filter(*function*,*iterable*)
Construct a new array from those elements of *iterable* for which *function* returns true.
```javascript
filter(function(el,ind,list){ return el%2==0 }, [3, 1, 4]); // returns [4]
```
this: 3.14159
args: 3,14,1,5,9
<a name="filter.async" />
## filter.async(*function*,*iterable*, *callback*)
Call async *function* once for each element in *iterable*, receiving a boolean
parameter, and construct a new array of all the values for which *function*
produces *true*
```javascript
var users = [ 3, 5, 8, 13, 21 ]; // only user#3 and user#8 have permission in this example
function hasPermission(userId, callback){ ... callback(/* true or false */); }
filter.async(hasPermission, [3, 1, 4], function(permittedUsers){
assert.equal(permittedUsers.length, /* ? */);
});
```
## each(*function*,*iterable*)
<a name="juxt" />
## juxt(*functions ...*)
Call *function* once for element in *iterable*.
Take a set of functions, return a function that is the juxtaposition of those
functions. The returned function takes a variable number of arguments and
returns a list containing the result of applying each fn to the arguments.
```javascript
each(function(el,ind,list){ console.assert( el == list[ind] ); }, [3,1,4]);
function inc1(n){ return n+1 };
function inc2(n){ return n+2 };
function inc3(n){ return n+3 };
juxt(inc1, inc2, inc3)(314); // returns [315,316,317]
```
<a name="juxt.async" />
## juxt.async(*functions ...*)
Async implementation of *juxt*.
```javascript
function turkish(word, callback){ /* some magic here */ }
function french(word, callback){ /* some magic here */ }
function polish(word, callback){ /* some magic here */ }
juxt.async(turkish, french, polish)("hello", function(error, results){
assert.equal(results[0], "merhaba");
assert.equal(results[1], "bonjour");
assert.equal(results[2], "cześć");
});
```
<a name="map" />
## map(*function*,*iterable*)

@@ -153,7 +249,7 @@

function square(n){
function square(n){
return n*n;
}
map(square,[3,1,4,1,5,9]); // returns [9,1,16,1,25,81]
map(square, [3,1,4,1,5,9]); // returns [9,1,16,1,25,81]
```

@@ -170,5 +266,6 @@

map(capitalize, dict); // returns { 'en':'Hello', 'tr':'Merhaba', 'fr':'Bonjour' }
map(capitalize, capitalize); // returns { 'en':'Hello', 'tr':'Merhaba', 'fr':'Bonjour' }
```
<a name="map.async" />
## map.async(*function*,*iterable*, *callback*)

@@ -189,60 +286,72 @@

## filter(*function*,*iterable*)
<a name="memoize" />
## memoize(*function*,*hasher*)
Construct a new array from those elements of *iterable* for which *function* returns true.
Return a memoized version of *function*. *hasher* is optional.
```javascript
filter(function(el,ind,list){ return el%2==0 },[3,1,4]); // returns [4]
> function myfunc(n){
console.log("doing some work");
return n + 10;
}
> var myfuncMemo = memoize(myfunc);
> myfuncMemo(1);
"doing some work"
11
> myfuncMemo(1);
11
> myfuncMemo(20);
"doing some work"
30
> myfuncMemo(20);
30
```
## filter.async(*function*,*iterable*, *callback*)
<a name="memoize.async" />
## memoize.async(*function*, *hasher*)
Call async *function* once for each element in *iterable*, receiving a boolean
parameter, and construct a new array of all the values for which *function*
produces *true*
Memoize given async *function* if it doesn't produce any error.
```javascript
> function readFile(){ console.log('doing some work'); ... callback(undefined, buffer); }
var users = [ 3, 5, 8, 13, 21 ]; // only user#3 and user#8 have permission in this example
> var readFileMemo = memoize.async(readFile);
function hasPermission(userId, callback){ ... callback(/* true or false */); }
> readFileMemo('/docs/readme', function(error, content){
console.log(content);
});
"doing some work"
filter.async(hasPermission, users, function(permittedUsers){
assert.equal(permittedUsers.length, 4);
> "This is the Readme file"
> readFileMemo('/docs/readme', function(error, content){
console.log(content);
});
"This is the Readme file"
```
<a name="partial" />
## partial(*function*,*initial arguments*,*context *)
Return a new function which will call *function* with the gathered arguments.
## juxt(*functions ...*)
```javascript
function testPartial(){
var args = reduce(function(x,y){ x+", "+y },arguments);
Take a set of functions, return a function that is the juxtaposition of those
functions. The returned function takes a variable number of arguments and
returns a list containing the result of applying each fn to the arguments.
console.log("this:",this);
console.log("args:",args);
}
```javascript
function inc1(n){ return n+1 };
function inc2(n){ return n+2 };
function inc3(n){ return n+3 };
juxt(inc1, inc2, inc3)(314); // returns [315,316,317]
partial(testPartial, [3,14], 3.14159)(1,5,9);
```
## juxt.async(*functions ...*)
Async implementation of *juxt*.
```javascript
function turkish(word, callback){ /* some magic here */ }
function french(word, callback){ /* some magic here */ }
function polish(word, callback){ /* some magic here */ }
juxt.async(turkish, french, polish)("hello", function(error, results){
assert.equal(results[0], "merhaba");
assert.equal(results[1], "bonjour");
assert.equal(results[2], "cześć");
});
The example code above will output:
```
this: 3.14159
args: 3,14,1,5,9
```
<a name="reduce />
## reduce(*function*,*iterable*)

@@ -257,2 +366,3 @@

<a name="reduce.async" />
## reduce.async(*function*,*iterable*, *callback*)

@@ -276,3 +386,27 @@

# Testing
## On NodeJS:
```
$ npm test
```
## On Browsers
Run `make test` command to publish the tests on `localhost:1314`. Visit the URL using the browser on which you want to run the tests. Stop the server (Ctrl+C) when you're done with testing.
To see the summary of results;
```
$ make test do=verify
Not Tested: firefox, ie8, ie7
Passed: ie6, webkit
Revision: 1.3.0
Results Source: test/results.json
Config: test/config.json
```
# SEE ALSO
- [Functional Programming - Eloquent JavaScript](http://eloquentjavascript.net/chapter6.html)

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc