rods-util

A collection of small utility methods.

Rod's Node.js Utilities

A small library of utility functions and classes, primarily intended for use within server-side JavaScript (CoffeeScript).

The module is published as rods-util on npm. It has no (runtime) external dependencies.

You can install rods-util directly through npm:

npm install rods-util -g

(omit the -g flag to install the module in a local node_modules directory rather than the global one).

or by adding it as a dependency in your package.json:

"dependencies": { "rods-util": "latest" }

To use the module, simply require it:

var S = require('rods-util').StringUtil;
var hello = ' hello.  ';
console.log(hello);         // outputs: " hello.  " 
console.log(S.trim(hello)); // outputs: "hello." 

See the test suite for more examples.

The module is divided into several independent collections of utility methods.

Currently (as of version 0.4.0) there are five collections:

  1. ContainerUtil - provides utility methods that operate on containers like Arrays and Maps.

  2. FileUtil - provides utility methods that operate on Files and related objects.

  3. FunctorUtil - provides utility methods that manipulate functions and support function-oriented programming. (Here is where you'll find things like function composition, asynchronous loops, etc.)

  4. Stopwatch - is a simple timer that can be used to time synchronous and asynchronous activities.

  5. StringUtil - provides utility methods that operate on Strings.

Each is described in more detail below.

(These documents may be incomplete or slightly out-of-date. See the test suite (./test/*.coffee) for more examples and/or a more comprehensive and up-to-date description.)

ContainerUtil provides utility methods that operate on containers like Arrays and Maps.

To import the ContainerUtil:

var CU = require('rods-util').ContainerUtil;

Creates a (shallow) copy of a map or object.

Example:

var original = { a: 1, b: 'two' };
var clone = CU.clone(original);
 
console.log('original.a is',original.a); // outputs: "original.a is 1" 
console.log('clone.a is',clone.a);       // outputs: "clone.a is 1" 
 
clone.= 2
console.log('original.a is',original.a); // outputs: "original.a is 1" 
console.log('clone.a is',clone.a);       // outputs: "clone.a is 2" 

Creates a (deep) copy of a map or object.

Example:

var original = { a: 1, b: 'two', c: { x:'alpha', y:'beta' } };
var clone = CU.deep_clone(original);
console.log('original.c.x is',original.c.x); // outputs: "original.c.x is alpha" 
console.log('clone.c.x is',clone.c.x);       // outputs: "clone.c.x is alpha" 
clone.c.x = 'gamma'
console.log('original.c.x is',original.c.x); // outputs: "original.c.x is alpha" 
console.log('clone.c.x is',clone.c.x);       // outputs: "clone.c.x is gamma" 

Creates an array of name/value pairs from an object or map.

Example:

var m = { a: 1, b: 'two' };
var a = CU.object_to_array(m);
console.log(a); // outputs:  [ ['a',1], ['b','two'] ] 

An alias for object_to_array (which see).

Convert an object (map) into an array of values.

Example:

var m = { a: 1, b: 'two' };
var a = CU.object_vales(m);
// Array a is now:  [ 1, 'two' ] 

Converts an array into a map whose keys are the unique elements in the array and whose values are the number of times the element appears in array.

Example:

var a = [ 'a', 'b', 'c', 'b', 'c', 'b' ];
var c = CU.frequency_count(a);
console.log(c); // outputs: { a:1, b:3, c:2 } 

Converts a map into an array of name/value pairs, ordered by value.

Example:

var m = { a:2, c:1, b:3 };
var a = CU.sort_by_value(m);
console.log(a); // outputs: [ ['c',1], ['a',2], ['b',3] ] 

Converts a map into an array of name/value pairs, ordered by name (key).

Example:

var m = { a:2, c:1, b:3 };
var a = CU.sort_by_key(m);
console.log(a); // outputs: [ ['a',2], ['b',3], ['c',1] ] 

FileUtil provides utility methods that operate on files and related objects

To import the FileUtil:

var FU = require('rods-util').FileUtil;

Read the file at filename into a string.

var callback = function(err,contents) {
  if(err) {
    // an error occured 
  } else {
    // process contents 
  }
};
FU.file_to_string('MY-FILE.TXT',callback);

A synchronous version of file_to_string.

var contents = FU.file_to_string_sync('MY-FILE.TXT');

A convenience method that combines FileUtil.file_to_string and StringUtil.string_to_array.

var callback = function(err,lines) {
  if(err) {
    // an error occured 
  } else {
    // process lines 
  }
};
FU.file_to_array('MY-FILE.TXT',callback);

Note that the options map may contain an encoding as well as the various options supported by string_to_array (which see).

A synchronous version of file_to_array.

var lines = FU.file_to_array_sync('MY-FILE.TXT');

To import the FunctorUtil:

var FnU = require('rods-util').FunctorUtil;

Predicate methods provide utilties that operate on predicates (functions that return a boolean (true/false) value).

Returns a function that yields a constant true:

var predicate = FnU.true();
console.log( predicate() ); // outputs: true 

Returns a function that yields a constant false:

var predicate = FnU.false();
console.log( predicate() ); // outputs: false 

Returns a function that yields the opposite of the given predicates.

var yes = FnU.true();
var predicate = FnU.not(yes);
console.log( predicate() ); // outputs: false 

Returns a function that yields true if and only if all the given predicates yield true.

var p1 = FnU.true();
var p2 = FnU.false();
var p3 = FnU.true();
var predicate = FnU.and( p1, p2, p3 );
console.log( predicate() ); // outputs: false 
var another = FnU.and( p1, p3 );
console.log( another() ); // outputs: true 

Returns a function that yields true if any of the given predicates yield true.

var p1 = FnU.true();
var p2 = FnU.false();
var p3 = FnU.false();
var predicate = FnU.or( p1, p2, p3 );
console.log( predicate() ); // outputs: true 
var another = FnU.and( p2, p3 );
console.log( another() ); // outputs: false 

Returns a function that yields true if exactly one of the given predicates yield true.

var p1 = FnU.true();
var p2 = FnU.false();
var p3 = FnU.true();
var p4 = FnU.false();
var predicate = FnU.or( p1, p2, p4 );
console.log( predicate() ); // outputs: true 
var another = FnU.and( p1, p2, p3 );
console.log( another() ); // outputs: false 

Function methods provide utilties that operate on functions.

Given a function f(a,b) returns a function equivalent to f(b,a).

Note that any arguments after the first two remain unchanged.

Given a function f(a,b,c,...,z) returns a function equivalent to f(z,...c,b,a).

Given the functions f and g, returns a function equivalent to f(g()).

Given the functions f, g and h, returns a function equivalent to f(g(h())), and so on.

Provides a functor-based for-loop.

Accepts 5 function-valued parameters:

  • init - an initialization function (no arguments passed, no return value is expected)
  • condition - a predicate that indicates whether we should continue looping (no arguments passed, a boolean value is expected to be returned)
  • action - the action to take in each pas through the loop (no arguments passed, no return value is expected)
  • step - called at the end of every action, prior to condition (no arguments passed, no return value is expected)
  • whendone - called at the end of the loop (when condition returns false), (no arguments passed, no return value is expected).

This method largely exists for symmetry with for_async.

Executes an asynchronous for-loop.

Accepts 5 function-valued parameters:

  • init - an initialization function (no arguments passed, no return value is expected)
  • condition - a predicate that indicates whether we should continue looping (no arguments passed, a boolean value is expected to be returned)
  • action - the action to take in each pas through the loop (no arguments passed, no return value is expected)
  • step - called at the end of every action, prior to condition (no arguments passed, no return value is expected)
  • whendone - called at the end of the loop (when condition returns false), (no arguments passed, no return value is expected).

For example, the loop:

for(var i=0; i<10; i++) { console.log(i); }

Could be implemented as:

var i = 0;
init = function() { i = 0; };
cond = function() { return i < 10; };
actn = function(next) { console.log(i); next(); };
incr = function() { i = i + 1; };
done = function() { };
for_async(init,cond,actn,incr,done);

Provides a functor-based for-each-loop.

Accepts 3 parameters:

  • list - the array to iterate over
  • action - the function indicating the action to take (with the signature (value,index,list))
  • whendone - called at the end of the loop

This method doesn't add much value over the built-in Array.forEach, but exists for symmetry with for_each_async.

Executes an asynchronous for-each loop.

Accepts 3 parameters:

  • list - the array to iterate over
  • action - the function indicating the action to take (with the signature (value,index,list))
  • whendone - called at the end of the loop

This method largely exists for symmetry with for_each_async.

For example, the loop

[0..10].foreach (elt,index,array)-> console.log elt

(That's in CoffeeScript, not JavaScript.)

Could be implemented as:

for_each_async [0..10](elt,index,array,next)->
  console.log elt
  next()

For a given synchronous function f(a,b,c,...), returns a new function g(a,b,c,...,callback) that is equivalent to callback(f(a,b,c,...)).

The resulting method isn't asynchronous, but approximates the method signature and control flow used by asynchronous methods. This makes it easy to use a synchronous method where an asynchronous one is expected.

Invokes each of the given asynchronous methods immediately (passing the corresponding args_for_methods, if any), and collects the response from each.

When all methods have invoked their callbacks, the specified callback is invoked, passing an array containing the callback arguments from each method.

For example:

sum       = (a,b,callback)->callback(a+b)
product   = (a,b,callback)->callback(a*b)
identity  = (a,b,callback)->callback(a,b)
 
methods   = [ sumproductidentity ]
arguments = [ [ 34][ 34 ][ 34 ]
 
FnU.fork methodsarguments(results)->
 console.log results[0# yields: 7 
 console.log results[1# yields: 12 
 console.log results[3# yields: [ 3, 4 ] 

(That's in CoffeeScript, not JavaScript.)

Just like fork, but ensures no more than max of the methods are running at the same time.

Removes leading and trailing whitespace from the given string.

Both vertical (\n, \r\f, etc.) and horizonal (\t, , etc.) whitespace are removed.

var S = require('rods-util').StringUtil;
S.trim("\t hello  \n"); // returns "hello" 

Only the leading and trailing whitespace is removed. Whitespace that appears "within" the text of the string is left intact.

S.trim("\t hello  \n\tworld \n"); // returns "hello  \n\tworld" 

Equivalent to comment_stripper('#','\\'), which see.

Returns a function that will strip (inline) comments of the specified format from input strings.

The comment_char and all subsquent characters (thru the end of the string) will be removed.

An instance of comment_char that is immediately proceeded by escape_char will be treated as a literal comment_char. (Other instances of escape_char will be treated as a literal escape_char.)

Example:

var S = require('rods-util').StringUtil;
var f = S.comment_stripper('%','}');
f("This is text. % This is comment."); // returns ""This is text. " 
f("25}% of 20 is 5");                  // returns "25% of 20 is 5" 

The StringUtil.strip_comment method is a comment stripper with # as the comment delimiter, and \ as the escape character. (Note that since \ is JavaScript's escape character, you must write "\\" to pass "\". E.g.: f = S.comment_stripper('#','\\') will create a comment stripper with a single backslash as the escape character.

Returns a representation of str that can be passed to the RegExp constructor in order to match the literal sequence found in str.

Example:

var S = require('rods-util').StringUtil;
var dot_paren = S.escape_for_regexp('.)'); // returns `\.\)` 
var re = new RegExp('^[A-Z]'+dot_paren)    // returns /^[A-Z]\.\)/ 
re.test("A.)")                             // returns true 
re.test("A\.\)")                           // returns false 

Returns true if the given string is null, empty ("") or only contains whitespace characters.

Returns true if the given string is not null, not empty ("") and contains at least one non-whitespace character.

Splits a string into an array of strings with various configurable options.

  • options.delimiter - a pattern on which to split the string (defaults to /[\n\r\f\v]/)
  • options.comment_char - when present (and not false) this and all subsequent characters (up to the next delimiter) will be stripped (defaults to '#')
  • options.comment_char_escape - when present, a character than can be used to "escape" a literal comment character (defaults to a single backslash).
  • options.trim - when true, remove leading and trailing whitespace characters from each "line" (defaults to true)
  • options.strip_blanks - when true, remove empty lines from the returned array (defaults to true)

For example, given a string str such as:

Line 1

Line 3 # with a comment
  Line 4
# Line 5 is all comment
Line 6 has an \# escaped comment.

then:

var S = require('rods-util').StringUtil;
S.string_to_array(str);

will yield:

Line 1
Line 3
  Line 4
Line 6 has an # escaped comment.

This software and associated materials are made available under the terms of the Apache License, Version 2.0, an OSD-compliant, non-viral, open source license. Use it in good health.

See the license.txt file for details.