From c457d9a3dfdbd216b98da945efd7cc6b986abb39 Mon Sep 17 00:00:00 2001 From: kgryte Date: Sat, 28 Feb 2015 01:49:44 -0800 Subject: [PATCH 1/3] [FIX] i=1 bug. [UPDATE] support accessor. fmt. empty array returns null. dev deps. [TESTS] accessor. --- README.md | 38 ++++++++++++--- examples/index.js | 10 ++-- lib/index.js | 69 +++++++++++++++----------- package.json | 19 ++++++-- test/test.js | 121 ++++++++++++++++++++++++++++++++++++++-------- 5 files changed, 193 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index 03e48a0..210f196 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ nanrange === [![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Coverage Status][coveralls-image]][coveralls-url] [![Dependencies][dependencies-image]][dependencies-url] -> Computes the arithmetic range of an array of values ignoring all non-numeric elements. +> Computes the arithmetic range of an array ignoring non-numeric values. ## Installation @@ -19,15 +19,41 @@ For use in the browser, use [browserify](https://github.com/substack/node-browse var nanrange = require( 'compute-nanrange' ); ``` -#### nanrange( arr ) +#### nanrange( arr[, accessor] ) -Returns the range of an `array` of values ignoring all non-numeric elements. +Computes the range of an `array` ignoring non-numeric values. For primitive `arrays`, ``` javascript -var r = range( [2, null, 3, 4, null, 1] ); +var arr = [ 2, null, 3, 4, null, 1 ]; + +var r = range( arr ); +// returns [1,4] +``` + +For object `arrays`, provide an accessor `function` for accessing `array` values + +``` javascript +var arr = [ + [1,2], + [2,null], + [3,3], + [4,4], + [5,null], + [6,1] +]; + +function getValue( d ) { + return d[ 1 ]; +} + +var r = range( arr, getValue ); // returns [1,4] ``` +__Note__: if an input `array` does not contain any `numeric` values, the function returns `null`. + + + ## Examples ``` javascript @@ -41,9 +67,7 @@ for ( var i = 0; i < data.length; i++ ) { data[ i ] = Math.random()*100; } } - console.log( nanrange( data ) ); - ``` To run the example code from the top-level application directory, @@ -52,6 +76,8 @@ To run the example code from the top-level application directory, $ node ./examples/index.js ``` + + ## Tests ### Unit diff --git a/examples/index.js b/examples/index.js index dbffb7a..ae6fff0 100644 --- a/examples/index.js +++ b/examples/index.js @@ -4,11 +4,11 @@ var nanrange = require( './../lib' ); var data = new Array( 100 ); for ( var i = 0; i < data.length; i++ ) { - if( i % 2 === 0 ){ - data[ i ] = null; - } else { - data[ i ] = Math.random()*100; - } + if( i % 2 === 0 ){ + data[ i ] = null; + } else { + data[ i ] = Math.random()*100; + } } console.log( nanrange( data ) ); diff --git a/lib/index.js b/lib/index.js index 4f1ed3a..c3608a5 100644 --- a/lib/index.js +++ b/lib/index.js @@ -4,7 +4,7 @@ * * * DESCRIPTION: -* - Computes the arithmetic range of an array of values ignoring all non-numeric elements. +* - Computes the arithmetic range of an array ignoring non-numeric values. * * * NOTES: @@ -30,40 +30,53 @@ // MODULES // -var isArray = require( 'validate.io-array' ); -var isNumber = require( 'validate.io-number' ); +var isArray = require( 'validate.io-array' ),isNumber = require( 'validate.io-number' ); -// FUNCTIONS // + +// NANRANGE // /** -* FUNCTION: nanrange( arr ) -* Computes the arithmetic range of an array of values ignoring all -* non-numeric elements +* FUNCTION: nanrange( arr[, accessor] ) +* Computes the arithmetic range of an array ignoring non-numeric values. +* +* @param {Array} arr - input array +* @param {Function} [accessor] - accessor function for accessing array values +* @returns {Array|null} arithmetic range or null */ -function nanrange( arr ) { - if ( !isArray( arr ) ) { - throw new TypeError( 'range()::invalid input argument. Must provide an array.' ); - } - var len = arr.length, - min = null, - max = min, - x; - for ( var i = 1; i < len; i++ ) { - x = arr[ i ]; +function nanrange( arr, clbk ) { + if ( !isArray( arr ) ) { + throw new TypeError( 'range()::invalid input argument. Must provide an array. Value: `' + arr + '`.' ); + } + if ( arguments.length > 1 && typeof clbk !== 'function' ) { + throw new TypeError( 'range()::invalid input argument. Accessor must be a function. Value: `' + clbk + '`.' ); + } + var len = arr.length, + min = null, + max = min, + flg = true, + x; - if ( !isNumber( x ) ) { - continue; - } - if ( min === null || x < min ) { - min = x; - } - if ( max === null || x > max ) { - max = x; - } - } - return [ min, max ]; + for ( var i = 0; i < len; i++ ) { + x = ( clbk ) ? clbk( arr[i] ) : arr[ i ]; + if ( !isNumber( x ) ) { + continue; + } + if ( flg ) { + min = x; + max = x; + flg = false; + continue; + } + if ( x < min ) { + min = x; + } else if ( x > max ) { + max = x; + } + } + return ( flg ) ? null : [ min, max ]; } // end FUNCTION nanrange() // EXPORTS // + module.exports = nanrange; diff --git a/package.json b/package.json index a1bf520..4504788 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "compute-nanrange", "version": "0.9.0", - "description": "Computes the arithmetic range of an array of values ignoring all non-numeric elements.", + "description": "Computes the arithmetic range of an array ignoring non-numeric values.", "author": { "name": "Philipp Burckhardt", "email": "pburckhardt@outlook.com" @@ -10,6 +10,10 @@ { "name": "Philipp Burckhardt", "email": "pburckhardt@outlook.com" + }, + { + "name": "Athan Reines", + "email": "kgryte@gmail.com" } ], "scripts": { @@ -28,8 +32,15 @@ "computation", "statistics", "stats", + "mathematics", + "math", "range", - "arithmetic" + "arithmetic", + "min", + "max", + "minimum", + "maximum", + "extremes" ], "bugs": { "url": "https://github.com/compute-io/nanrange/issues" @@ -39,8 +50,8 @@ "validate.io-number": "^1.0.3" }, "devDependencies": { - "chai": "1.x.x", - "mocha": "1.x.x", + "chai": "2.x.x", + "mocha": "2.x.x", "coveralls": "^2.11.1", "istanbul": "^0.3.0", "jshint": "2.x.x", diff --git a/test/test.js b/test/test.js index 8589d3c..3dffe02 100644 --- a/test/test.js +++ b/test/test.js @@ -26,33 +26,112 @@ describe( 'compute-nanrange', function tests() { it( 'should throw an error if not provided an array', function test() { var values = [ - '5', - 5, - null, - undefined, - NaN, - function(){}, - {} - ]; - for ( var i = 0; i < values.length; i++ ) { - expect( badValue( values[i] ) ).to.throw( TypeError ); - } - function badValue( value ) { - return function() { - nanrange( value ); - }; - } - }); - - it( 'should return the arithmetic range', function test() { - var data = [ 3, 4, 2, 1, 4 ], + '5', + 5, + null, + undefined, + NaN, + true, + function(){}, + {} + ]; + for ( var i = 0; i < values.length; i++ ) { + expect( badValue( values[i] ) ).to.throw( TypeError ); + } + function badValue( value ) { + return function() { + nanrange( value ); + }; + } + }); + + it( 'should throw an error if provided an accessor which is not a function', function test() { + var values = [ + '5', + 5, + null, + undefined, + NaN, + true, + [], + {} + ]; + for ( var i = 0; i < values.length; i++ ) { + expect( badValue( values[i] ) ).to.throw( TypeError ); + } + function badValue( value ) { + return function() { + nanrange( [], value ); + }; + } + }); + + it( 'should compute the arithmetic range', function test() { + var data, expected; + + data = [ 3, 4, 2, 1, 4 ]; expected = [ 1, 4 ]; + assert.deepEqual( nanrange( data ), expected ); }); it( 'should ignore non-numeric values', function test() { - var data = [ 3, null, 4, 2, 1, null, 4, 6 ], + var data, expected; + + data = [ 3, null, 4, 2, 1, null, 4, 6 ]; expected = [ 1, 6 ]; + + assert.deepEqual( nanrange( data ), expected ); + }); + + it( 'should compute the arithmetic range using an accessor function', function test() { + var data, expected, actual; + + data = [ + [1,3], + [2,null], + [3,4], + [4,2], + [5,1], + [6,null], + [7,4], + [8,6] + ]; + + expected = [ 1, 6 ]; + actual = nanrange( data, getValue ); + + assert.deepEqual( actual, expected ); + + function getValue( d ) { + return d[ 1 ]; + } + }); + + it( 'should return null is provided either an empty array or an array without any numeric values', function test() { + var data, expected; + + data = [ + null, + false, + undefined, + '', + NaN, + [], + {} + ]; + expected = null; + + assert.strictEqual( nanrange( [] ), expected ); + assert.strictEqual( nanrange( data ), expected ); + }); + + it( 'should compute an arithmetic range even if only provided an array containing a single numeric value', function test() { + var data, expected; + + data = [ 5 ]; + expected = [ 5, 5 ]; + assert.deepEqual( nanrange( data ), expected ); }); From 6175e609899443b5991a362acab33bc61f14374c Mon Sep 17 00:00:00 2001 From: kgryte Date: Sat, 28 Feb 2015 01:52:11 -0800 Subject: [PATCH 2/3] [UPDATE] README. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 210f196..21a9e39 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ var nanrange = require( 'compute-nanrange' ); #### nanrange( arr[, accessor] ) -Computes the range of an `array` ignoring non-numeric values. For primitive `arrays`, +Computes the arithmetic range of an `array` ignoring non-numeric values. For primitive `arrays`, ``` javascript var arr = [ 2, null, 3, 4, null, 1 ]; From bd426e092bf1f29936192021d6cd26d0b86e791d Mon Sep 17 00:00:00 2001 From: kgryte Date: Sat, 28 Feb 2015 01:53:58 -0800 Subject: [PATCH 3/3] [UPDATE] examples fmt. --- README.md | 10 +++++----- examples/index.js | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 21a9e39..0151f0b 100644 --- a/README.md +++ b/README.md @@ -61,11 +61,11 @@ var nanrange = require( 'compute-nanrange' ); var data = new Array( 100 ); for ( var i = 0; i < data.length; i++ ) { - if( i % 2 === 0 ){ - data[ i ] = null; - } else { - data[ i ] = Math.random()*100; - } + if ( i % 2 === 0 ){ + data[ i ] = null; + } else { + data[ i ] = Math.random()*100; + } } console.log( nanrange( data ) ); ``` diff --git a/examples/index.js b/examples/index.js index ae6fff0..9ed9491 100644 --- a/examples/index.js +++ b/examples/index.js @@ -4,7 +4,7 @@ var nanrange = require( './../lib' ); var data = new Array( 100 ); for ( var i = 0; i < data.length; i++ ) { - if( i % 2 === 0 ){ + if ( i % 2 === 0 ){ data[ i ] = null; } else { data[ i ] = Math.random()*100;