Comparing version 0.0.4 to 0.1.0
@@ -12,3 +12,9 @@ if (typeof Map === "undefined") { | ||
}; | ||
} | ||
} else (function() { | ||
var m = new Map; | ||
if (m.set(0, 0) !== m) { | ||
m = m.set; | ||
Map.prototype.set = function() { m.apply(this, arguments); return this; }; | ||
} | ||
})(); | ||
@@ -21,7 +27,3 @@ (function (global, factory) { | ||
function length(d) { | ||
return d.length; | ||
} | ||
var min = function(array, f) { | ||
function min(array, f) { | ||
var i = -1, | ||
@@ -45,3 +47,3 @@ n = array.length, | ||
var transpose = function(matrix) { | ||
function transpose(matrix) { | ||
if (!(n = matrix.length)) return []; | ||
@@ -54,13 +56,15 @@ for (var i = -1, m = min(matrix, length), transpose = new Array(m); ++i < m;) { | ||
return transpose; | ||
}function length(d) { | ||
return d.length; | ||
} | ||
var zip = function() { | ||
function zip() { | ||
return transpose(arguments); | ||
} | ||
var number = function(x) { | ||
function number(x) { | ||
return x === null ? NaN : +x; | ||
} | ||
var variance = function(array, f) { | ||
function variance(array, f) { | ||
var n = array.length, | ||
@@ -97,3 +101,3 @@ m = 0, | ||
var values = function(map) { | ||
function _values(map) { | ||
var values = []; | ||
@@ -104,3 +108,3 @@ for (var key in map) values.push(map[key]); | ||
var sum = function(array, f) { | ||
function sum(array, f) { | ||
var s = 0, | ||
@@ -122,3 +126,3 @@ n = array.length, | ||
var shuffle = function(array, i0, i1) { | ||
function shuffle(array, i0, i1) { | ||
if ((m = arguments.length) < 3) { | ||
@@ -143,9 +147,98 @@ i1 = array.length; | ||
function scale(x) { | ||
var k = 1; | ||
while (x * k % 1) k *= 10; | ||
return k; | ||
var prefix = "$"; | ||
function Map() {} | ||
Map.prototype = _map.prototype = { | ||
has: function(key) { | ||
return (prefix + key) in this; | ||
}, | ||
get: function(key) { | ||
return this[prefix + key]; | ||
}, | ||
set: function(key, value) { | ||
return this[prefix + key] = value; | ||
}, | ||
remove: function(key) { | ||
var property = prefix + key; | ||
return property in this && delete this[property]; | ||
}, | ||
keys: function() { | ||
var keys = []; | ||
for (var property in this) if (property[0] === prefix) keys.push(property.slice(1)); | ||
return keys; | ||
}, | ||
values: function() { | ||
var values = []; | ||
for (var property in this) if (property[0] === prefix) values.push(this[property]); | ||
return values; | ||
}, | ||
entries: function() { | ||
var entries = []; | ||
for (var property in this) if (property[0] === prefix) entries.push({key: property.slice(1), value: this[property]}); | ||
return entries; | ||
}, | ||
size: function() { | ||
var size = 0; | ||
for (var property in this) if (property[0] === prefix) ++size; | ||
return size; | ||
}, | ||
empty: function() { | ||
for (var property in this) if (property[0] === prefix) return false; | ||
return true; | ||
}, | ||
forEach: function(f) { | ||
for (var property in this) if (property[0] === prefix) f.call(this, property.slice(1), this[property]); | ||
} | ||
}; | ||
function _map(object, f) { | ||
var map = new Map; | ||
// Copy constructor. | ||
if (object instanceof Map) object.forEach(function(key, value) { map.set(key, value); }); | ||
// Index array by numeric index or specified key function. | ||
else if (Array.isArray(object)) { | ||
var i = -1, | ||
n = object.length, | ||
o; | ||
if (arguments.length === 1) while (++i < n) map.set(i, object[i]); | ||
else while (++i < n) map.set(f.call(object, o = object[i], i), o); | ||
} | ||
// Convert object to map. | ||
else for (var key in object) map.set(key, object[key]); | ||
return map; | ||
} | ||
var range = function(start, stop, step) { | ||
function Set() {} | ||
var proto = _map.prototype; | ||
Set.prototype = set.prototype = { | ||
has: proto.has, | ||
add: function(value) { | ||
value += ""; | ||
this[prefix + value] = true; | ||
return value; | ||
}, | ||
remove: proto.remove, | ||
values: proto.keys, | ||
size: proto.size, | ||
empty: proto.empty, | ||
forEach: function(f) { | ||
for (var property in this) if (property[0] === prefix) f.call(this, property.slice(1)); | ||
} | ||
}; | ||
function set(array) { | ||
var set = new Set; | ||
if (array) for (var i = 0, n = array.length; i < n; ++i) set.add(array[i]); | ||
return set; | ||
} | ||
function range(start, stop, step) { | ||
if ((n = arguments.length) < 3) { | ||
@@ -171,7 +264,10 @@ step = 1; | ||
return range; | ||
}function scale(x) { | ||
var k = 1; | ||
while (x * k % 1) k *= 10; | ||
return k; | ||
} | ||
// R-7 per <http://en.wikipedia.org/wiki/Quantile> | ||
var quantile = function(values, p) { | ||
function quantile(values, p) { | ||
var H = (values.length - 1) * p + 1, | ||
@@ -184,3 +280,3 @@ h = Math.floor(H), | ||
var permute = function(array, indexes) { | ||
function permute(array, indexes) { | ||
var i = indexes.length, permutes = new Array(i); | ||
@@ -191,3 +287,3 @@ while (i--) permutes[i] = array[indexes[i]]; | ||
var pairs = function(array) { | ||
function pairs(array) { | ||
var i = 0, n = array.length - 1, p0, p1 = array[0], pairs = new Array(n < 0 ? 0 : n); | ||
@@ -198,3 +294,3 @@ while (i < n) pairs[i] = [p0 = p1, p1 = array[++i]]; | ||
var nest = function() { | ||
function nest() { | ||
var keys = [], | ||
@@ -206,3 +302,3 @@ sortKeys = [], | ||
function map(array, depth) { | ||
function apply(array, depth, createResult, setResult) { | ||
if (depth >= keys.length) return rollup | ||
@@ -218,4 +314,5 @@ ? rollup.call(nest, array) : (sortValues | ||
value, | ||
valuesByKey = new Map, | ||
values; | ||
valuesByKey = _map(), | ||
values, | ||
result = createResult(); | ||
@@ -230,7 +327,7 @@ while (++i < n) { | ||
valuesByKey.forEach(function(values, key) { | ||
valuesByKey.set(key, map(values, depth)); | ||
valuesByKey.forEach(function(key, values) { | ||
setResult(result, key, apply(values, depth, createResult, setResult)); | ||
}); | ||
return valuesByKey; | ||
return result; | ||
} | ||
@@ -241,8 +338,7 @@ | ||
var array = new Array(map.size), | ||
i = -1, | ||
var array = [], | ||
sortKey = sortKeys[depth++]; | ||
map.forEach(function(value, key) { | ||
array[++i] = {key: key, values: entries(value, depth)}; | ||
map.forEach(function(key, value) { | ||
array.push({key: key, values: entries(value, depth)}); | ||
}); | ||
@@ -256,4 +352,5 @@ | ||
return nest = { | ||
map: function(array) { return map(array, 0); }, | ||
entries: function(array) { return entries(map(array, 0), 0); }, | ||
object: function(array) { return apply(array, 0, createObject, setObject); }, | ||
map: function(array) { return apply(array, 0, createMap, setMap); }, | ||
entries: function(array) { return entries(apply(array, 0, createMap, setMap), 0); }, | ||
key: function(d) { keys.push(d); return nest; }, | ||
@@ -264,5 +361,19 @@ sortKeys: function(order) { sortKeys[keys.length - 1] = order; return nest; }, | ||
}; | ||
}function createObject() { | ||
return {}; | ||
} | ||
var merge = function(arrays) { | ||
function setObject(object, key, value) { | ||
object[key] = value; | ||
} | ||
function createMap() { | ||
return _map(); | ||
} | ||
function setMap(map, key, value) { | ||
map.set(key, value); | ||
} | ||
function merge(arrays) { | ||
var n = arrays.length, | ||
@@ -289,7 +400,7 @@ m, | ||
var ascending = function(a, b) { | ||
function ascending(a, b) { | ||
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; | ||
} | ||
var median = function(array, f) { | ||
function median(array, f) { | ||
var numbers = [], | ||
@@ -311,3 +422,3 @@ n = array.length, | ||
var mean = function(array, f) { | ||
function mean(array, f) { | ||
var s = 0, | ||
@@ -330,3 +441,3 @@ n = array.length, | ||
var max = function(array, f) { | ||
function max(array, f) { | ||
var i = -1, | ||
@@ -350,3 +461,3 @@ n = array.length, | ||
var keys = function(map) { | ||
function keys(map) { | ||
var keys = []; | ||
@@ -357,3 +468,3 @@ for (var key in map) keys.push(key); | ||
var extent = function(array, f) { | ||
function extent(array, f) { | ||
var i = -1, | ||
@@ -384,3 +495,3 @@ n = array.length, | ||
var entries = function(map) { | ||
function entries(map) { | ||
var entries = []; | ||
@@ -391,3 +502,3 @@ for (var key in map) entries.push({key: key, value: map[key]}); | ||
var deviation = function() { | ||
function deviation() { | ||
var v = variance.apply(this, arguments); | ||
@@ -397,13 +508,7 @@ return v ? Math.sqrt(v) : v; | ||
var descending = function(a, b) { | ||
function descending(a, b) { | ||
return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; | ||
} | ||
function ascendingComparator(f) { | ||
return function(d, x) { | ||
return ascending(f(d), x); | ||
}; | ||
} | ||
var bisector = function(compare) { | ||
function bisector(compare) { | ||
if (compare.length === 1) compare = ascendingComparator(compare); | ||
@@ -432,11 +537,16 @@ return { | ||
}; | ||
}function ascendingComparator(f) { | ||
return function(d, x) { | ||
return ascending(f(d), x); | ||
}; | ||
} | ||
var ascendingBisect = bisector(ascending); | ||
exports.bisectRight = ascendingBisect.right; | ||
exports.bisectLeft = ascendingBisect.left; | ||
var bisect = exports.bisectRight; | ||
var bisectRight = ascendingBisect.right; | ||
var bisectLeft = ascendingBisect.left; | ||
exports.ascending = ascending; | ||
exports.bisect = bisect; | ||
exports.bisect = bisectRight; | ||
exports.bisectLeft = bisectLeft; | ||
exports.bisectRight = bisectRight; | ||
exports.bisector = bisector; | ||
@@ -448,2 +558,3 @@ exports.descending = descending; | ||
exports.keys = keys; | ||
exports.map = _map; | ||
exports.max = max; | ||
@@ -459,6 +570,7 @@ exports.mean = mean; | ||
exports.range = range; | ||
exports.set = set; | ||
exports.shuffle = shuffle; | ||
exports.sum = sum; | ||
exports.transpose = transpose; | ||
exports.values = values; | ||
exports.values = _values; | ||
exports.variance = variance; | ||
@@ -465,0 +577,0 @@ exports.zip = zip; |
@@ -1,1 +0,1 @@ | ||
"undefined"==typeof Map&&(Map=function(){this.clear()},Map.prototype={set:function(n,r){return this._[n]=r,this},get:function(n){return this._[n]},has:function(n){return n in this._},"delete":function(n){return n in this._&&delete this._[n]},clear:function(){this._=Object.create(null)},get size(){var n=0;for(var r in this._)++n;return n},forEach:function(n){for(var r in this._)n(this._[r],r,this)}}),function(n,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):r(n.arrays={})}(this,function(n){"use strict";function r(n){return n.length}function t(n){for(var r=1;n*r%1;)r*=10;return r}function e(n){return function(r,t){return d(n(r),t)}}var u=function(n,r){var t,e,u=-1,i=n.length;if(1===arguments.length){for(;++u<i;)if(null!=(e=n[u])&&e>=e){t=e;break}for(;++u<i;)null!=(e=n[u])&&t>e&&(t=e)}else{for(;++u<i;)if(null!=(e=r.call(n,n[u],u))&&e>=e){t=e;break}for(;++u<i;)null!=(e=r.call(n,n[u],u))&&t>e&&(t=e)}return t},i=function(n){if(!(f=n.length))return[];for(var t=-1,e=u(n,r),i=new Array(e);++t<e;)for(var f,a=-1,o=i[t]=new Array(f);++a<f;)o[a]=n[a][t];return i},f=function(){return i(arguments)},a=function(n){return null===n?0/0:+n},o=function(n,r){var t,e,u=n.length,i=0,f=0,o=-1,l=0;if(1===arguments.length)for(;++o<u;)isNaN(t=a(n[o]))||(e=t-i,i+=e/++l,f+=e*(t-i));else for(;++o<u;)isNaN(t=a(r.call(n,n[o],o)))||(e=t-i,i+=e/++l,f+=e*(t-i));return l>1?f/(l-1):void 0},l=function(n){var r=[];for(var t in n)r.push(n[t]);return r},s=function(n,r){var t,e=0,u=n.length,i=-1;if(1===arguments.length)for(;++i<u;)isNaN(t=+n[i])||(e+=t);else for(;++i<u;)isNaN(t=+r.call(n,n[i],i))||(e+=t);return e},c=function(n,r,t){(i=arguments.length)<3&&(t=n.length,2>i&&(r=0));for(var e,u,i=t-r;i;)u=Math.random()*i--|0,e=n[i+r],n[i+r]=n[u+r],n[u+r]=e;return n},h=function(n,r,e){(i=arguments.length)<3&&(e=1,2>i&&(r=n,n=0));var u=-1,i=0|Math.max(0,Math.ceil((r-n)/e)),f=t(Math.abs(e)),a=new Array(i);for(n*=f,e*=f;++u<i;)a[u]=(n+u*e)/f;return a},g=function(n,r){var t=(n.length-1)*r+1,e=Math.floor(t),u=+n[e-1],i=t-e;return i?u+i*(n[e]-u):u},v=function(n,r){for(var t=r.length,e=new Array(t);t--;)e[t]=n[r[t]];return e},p=function(n){for(var r,t=0,e=n.length-1,u=n[0],i=new Array(0>e?0:e);e>t;)i[t]=[r=u,u=n[++t]];return i},m=function(){function n(r,f){if(f>=i.length)return e?e.call(u,r):t?r.sort(t):r;for(var a,o,l,s=-1,c=r.length,h=i[f++],g=new Map;++s<c;)(l=g.get(a=h(o=r[s])+""))?l.push(o):g.set(a,[o]);return g.forEach(function(r,t){g.set(t,n(r,f))}),g}function r(n,t){if(t>=i.length)return n;var e=new Array(n.size),u=-1,a=f[t++];return n.forEach(function(n,i){e[++u]={key:i,values:r(n,t)}}),a?e.sort(function(n,r){return a(n.key,r.key)}):e}var t,e,u,i=[],f=[];return u={map:function(r){return n(r,0)},entries:function(t){return r(n(t,0),0)},key:function(n){return i.push(n),u},sortKeys:function(n){return f[i.length-1]=n,u},sortValues:function(n){return t=n,u},rollup:function(n){return e=n,u}}},y=function(n){for(var r,t,e,u=n.length,i=-1,f=0;++i<u;)f+=n[i].length;for(t=new Array(f);--u>=0;)for(e=n[u],r=e.length;--r>=0;)t[--f]=e[r];return t},d=function(n,r){return r>n?-1:n>r?1:n>=r?0:0/0},b=function(n,r){var t,e=[],u=n.length,i=-1;if(1===arguments.length)for(;++i<u;)isNaN(t=a(n[i]))||e.push(t);else for(;++i<u;)isNaN(t=a(r.call(n,n[i],i)))||e.push(t);return e.length?g(e.sort(d),.5):void 0},N=function(n,r){var t,e=0,u=n.length,i=-1,f=u;if(1===arguments.length)for(;++i<u;)isNaN(t=a(n[i]))?--f:e+=t;else for(;++i<u;)isNaN(t=a(r.call(n,n[i],i)))?--f:e+=t;return f?e/f:void 0},k=function(n,r){var t,e,u=-1,i=n.length;if(1===arguments.length){for(;++u<i;)if(null!=(e=n[u])&&e>=e){t=e;break}for(;++u<i;)null!=(e=n[u])&&e>t&&(t=e)}else{for(;++u<i;)if(null!=(e=r.call(n,n[u],u))&&e>=e){t=e;break}for(;++u<i;)null!=(e=r.call(n,n[u],u))&&e>t&&(t=e)}return t},M=function(n){var r=[];for(var t in n)r.push(t);return r},_=function(n,r){var t,e,u,i=-1,f=n.length;if(1===arguments.length){for(;++i<f;)if(null!=(e=n[i])&&e>=e){t=u=e;break}for(;++i<f;)null!=(e=n[i])&&(t>e&&(t=e),e>u&&(u=e))}else{for(;++i<f;)if(null!=(e=r.call(n,n[i],i))&&e>=e){t=u=e;break}for(;++i<f;)null!=(e=r.call(n,n[i],i))&&(t>e&&(t=e),e>u&&(u=e))}return[t,u]},w=function(n){var r=[];for(var t in n)r.push({key:t,value:n[t]});return r},A=function(){var n=o.apply(this,arguments);return n?Math.sqrt(n):n},x=function(n,r){return n>r?-1:r>n?1:r>=n?0:0/0},j=function(n){return 1===n.length&&(n=e(n)),{left:function(r,t,e,u){for(arguments.length<3&&(e=0),arguments.length<4&&(u=r.length);u>e;){var i=e+u>>>1;n(r[i],t)<0?e=i+1:u=i}return e},right:function(r,t,e,u){for(arguments.length<3&&(e=0),arguments.length<4&&(u=r.length);u>e;){var i=e+u>>>1;n(r[i],t)>0?u=i:e=i+1}return e}}},E=j(d);n.bisectRight=E.right,n.bisectLeft=E.left;var q=n.bisectRight;n.ascending=d,n.bisect=q,n.bisector=j,n.descending=x,n.deviation=A,n.entries=w,n.extent=_,n.keys=M,n.max=k,n.mean=N,n.median=b,n.merge=y,n.min=u,n.nest=m,n.pairs=p,n.permute=v,n.quantile=g,n.range=h,n.shuffle=c,n.sum=s,n.transpose=i,n.values=l,n.variance=o,n.zip=f}); | ||
"undefined"==typeof Map?(Map=function(){this.clear()},Map.prototype={set:function(n,t){return this._[n]=t,this},get:function(n){return this._[n]},has:function(n){return n in this._},"delete":function(n){return n in this._&&delete this._[n]},clear:function(){this._=Object.create(null)},get size(){var n=0;for(var t in this._)++n;return n},forEach:function(n){for(var t in this._)n(this._[t],t,this)}}):function(){var n=new Map;n.set(0,0)!==n&&(n=n.set,Map.prototype.set=function(){return n.apply(this,arguments),this})}(),function(n,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(n.arrays={})}(this,function(n){"use strict";function t(n,t){var r,e,u=-1,i=n.length;if(1===arguments.length){for(;++u<i;)if(null!=(e=n[u])&&e>=e){r=e;break}for(;++u<i;)null!=(e=n[u])&&r>e&&(r=e)}else{for(;++u<i;)if(null!=(e=t.call(n,n[u],u))&&e>=e){r=e;break}for(;++u<i;)null!=(e=t.call(n,n[u],u))&&r>e&&(r=e)}return r}function r(n){if(!(o=n.length))return[];for(var r=-1,u=t(n,e),i=new Array(u);++r<u;)for(var o,f=-1,a=i[r]=new Array(o);++f<o;)a[f]=n[f][r];return i}function e(n){return n.length}function u(){return r(arguments)}function i(n){return null===n?NaN:+n}function o(n,t){var r,e,u=n.length,o=0,f=0,a=-1,s=0;if(1===arguments.length)for(;++a<u;)isNaN(r=i(n[a]))||(e=r-o,o+=e/++s,f+=e*(r-o));else for(;++a<u;)isNaN(r=i(t.call(n,n[a],a)))||(e=r-o,o+=e/++s,f+=e*(r-o));return s>1?f/(s-1):void 0}function f(n){var t=[];for(var r in n)t.push(n[r]);return t}function a(n,t){var r,e=0,u=n.length,i=-1;if(1===arguments.length)for(;++i<u;)isNaN(r=+n[i])||(e+=r);else for(;++i<u;)isNaN(r=+t.call(n,n[i],i))||(e+=r);return e}function s(n,t,r){(i=arguments.length)<3&&(r=n.length,2>i&&(t=0));for(var e,u,i=r-t;i;)u=Math.random()*i--|0,e=n[i+t],n[i+t]=n[u+t],n[u+t]=e;return n}function l(){}function c(n,t){var r=new l;if(n instanceof l)n.forEach(function(n,t){r.set(n,t)});else if(Array.isArray(n)){var e,u=-1,i=n.length;if(1===arguments.length)for(;++u<i;)r.set(u,n[u]);else for(;++u<i;)r.set(t.call(n,e=n[u],u),e)}else for(var o in n)r.set(o,n[o]);return r}function h(){}function g(n){var t=new h;if(n)for(var r=0,e=n.length;e>r;++r)t.add(n[r]);return t}function v(n,t,r){(u=arguments.length)<3&&(r=1,2>u&&(t=n,n=0));var e=-1,u=0|Math.max(0,Math.ceil((t-n)/r)),i=p(Math.abs(r)),o=new Array(u);for(n*=i,r*=i;++e<u;)o[e]=(n+e*r)/i;return o}function p(n){for(var t=1;n*t%1;)t*=10;return t}function m(n,t){var r=(n.length-1)*t+1,e=Math.floor(r),u=+n[e-1],i=r-e;return i?u+i*(n[e]-u):u}function y(n,t){for(var r=t.length,e=new Array(r);r--;)e[r]=n[t[r]];return e}function d(n){for(var t,r=0,e=n.length-1,u=n[0],i=new Array(0>e?0:e);e>r;)i[r]=[t=u,u=n[++r]];return i}function N(){function n(t,o,f,a){if(o>=i.length)return e?e.call(u,t):r?t.sort(r):t;for(var s,l,h,g=-1,v=t.length,p=i[o++],m=c(),y=f();++g<v;)(h=m.get(s=p(l=t[g])+""))?h.push(l):m.set(s,[l]);return m.forEach(function(t,r){a(y,t,n(r,o,f,a))}),y}function t(n,r){if(r>=i.length)return n;var e=[],u=o[r++];return n.forEach(function(n,u){e.push({key:n,values:t(u,r)})}),u?e.sort(function(n,t){return u(n.key,t.key)}):e}var r,e,u,i=[],o=[];return u={object:function(t){return n(t,0,b,k)},map:function(t){return n(t,0,M,w)},entries:function(r){return t(n(r,0,M,w),0)},key:function(n){return i.push(n),u},sortKeys:function(n){return o[i.length-1]=n,u},sortValues:function(n){return r=n,u},rollup:function(n){return e=n,u}}}function b(){return{}}function k(n,t,r){n[t]=r}function M(){return c()}function w(n,t,r){n.set(t,r)}function _(n){for(var t,r,e,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(r=new Array(o);--u>=0;)for(e=n[u],t=e.length;--t>=0;)r[--o]=e[t];return r}function A(n,t){return t>n?-1:n>t?1:n>=t?0:NaN}function x(n,t){var r,e=[],u=n.length,o=-1;if(1===arguments.length)for(;++o<u;)isNaN(r=i(n[o]))||e.push(r);else for(;++o<u;)isNaN(r=i(t.call(n,n[o],o)))||e.push(r);return e.length?m(e.sort(A),.5):void 0}function E(n,t){var r,e=0,u=n.length,o=-1,f=u;if(1===arguments.length)for(;++o<u;)isNaN(r=i(n[o]))?--f:e+=r;else for(;++o<u;)isNaN(r=i(t.call(n,n[o],o)))?--f:e+=r;return f?e/f:void 0}function j(n,t){var r,e,u=-1,i=n.length;if(1===arguments.length){for(;++u<i;)if(null!=(e=n[u])&&e>=e){r=e;break}for(;++u<i;)null!=(e=n[u])&&e>r&&(r=e)}else{for(;++u<i;)if(null!=(e=t.call(n,n[u],u))&&e>=e){r=e;break}for(;++u<i;)null!=(e=t.call(n,n[u],u))&&e>r&&(r=e)}return r}function z(n){var t=[];for(var r in n)t.push(r);return t}function q(n,t){var r,e,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o;)if(null!=(e=n[i])&&e>=e){r=u=e;break}for(;++i<o;)null!=(e=n[i])&&(r>e&&(r=e),e>u&&(u=e))}else{for(;++i<o;)if(null!=(e=t.call(n,n[i],i))&&e>=e){r=u=e;break}for(;++i<o;)null!=(e=t.call(n,n[i],i))&&(r>e&&(r=e),e>u&&(u=e))}return[r,u]}function O(n){var t=[];for(var r in n)t.push({key:r,value:n[r]});return t}function K(){var n=o.apply(this,arguments);return n?Math.sqrt(n):n}function L(n,t){return n>t?-1:t>n?1:t>=n?0:NaN}function R(n){return 1===n.length&&(n=V(n)),{left:function(t,r,e,u){for(arguments.length<3&&(e=0),arguments.length<4&&(u=t.length);u>e;){var i=e+u>>>1;n(t[i],r)<0?e=i+1:u=i}return e},right:function(t,r,e,u){for(arguments.length<3&&(e=0),arguments.length<4&&(u=t.length);u>e;){var i=e+u>>>1;n(t[i],r)>0?u=i:e=i+1}return e}}}function V(n){return function(t,r){return A(n(t),r)}}var $="$";l.prototype=c.prototype={has:function(n){return $+n in this},get:function(n){return this[$+n]},set:function(n,t){return this[$+n]=t},remove:function(n){var t=$+n;return t in this&&delete this[t]},keys:function(){var n=[];for(var t in this)t[0]===$&&n.push(t.slice(1));return n},values:function(){var n=[];for(var t in this)t[0]===$&&n.push(this[t]);return n},entries:function(){var n=[];for(var t in this)t[0]===$&&n.push({key:t.slice(1),value:this[t]});return n},size:function(){var n=0;for(var t in this)t[0]===$&&++n;return n},empty:function(){for(var n in this)if(n[0]===$)return!1;return!0},forEach:function(n){for(var t in this)t[0]===$&&n.call(this,t.slice(1),this[t])}};var B=c.prototype;h.prototype=g.prototype={has:B.has,add:function(n){return n+="",this[$+n]=!0,n},remove:B.remove,values:B.keys,size:B.size,empty:B.empty,forEach:function(n){for(var t in this)t[0]===$&&n.call(this,t.slice(1))}};var C=R(A),D=C.right,F=C.left;n.ascending=A,n.bisect=D,n.bisectLeft=F,n.bisectRight=D,n.bisector=R,n.descending=L,n.deviation=K,n.entries=O,n.extent=q,n.keys=z,n.map=c,n.max=j,n.mean=E,n.median=x,n.merge=_,n.min=t,n.nest=N,n.pairs=d,n.permute=y,n.quantile=m,n.range=v,n.set=g,n.shuffle=s,n.sum=a,n.transpose=r,n.values=f,n.variance=o,n.zip=u}); |
@@ -9,2 +9,3 @@ import ascending from "./src/ascending"; | ||
import keys from "./src/keys"; | ||
import map from "./src/map"; | ||
import max from "./src/max"; | ||
@@ -20,2 +21,3 @@ import mean from "./src/mean"; | ||
import range from "./src/range"; | ||
import set from "./src/set"; | ||
import shuffle from "./src/shuffle"; | ||
@@ -39,2 +41,3 @@ import sum from "./src/sum"; | ||
keys, | ||
map, | ||
max, | ||
@@ -50,2 +53,3 @@ mean, | ||
range, | ||
set, | ||
shuffle, | ||
@@ -52,0 +56,0 @@ sum, |
{ | ||
"name": "d3-arrays", | ||
"version": "0.0.4", | ||
"version": "0.1.0", | ||
"description": "Array manipulation, ordering, searching, summarizing, etc.", | ||
@@ -34,4 +34,4 @@ "keywords": [ | ||
"tape": "4", | ||
"uglifyjs": "2" | ||
"uglify-js": "2" | ||
} | ||
} |
133
README.md
@@ -5,3 +5,3 @@ # d3-arrays | ||
When using D3—and with data visualization in general—you tend to do a lot of array manipulation. That’s because D3’s canonical representation of data is an array. Some common forms of array manipulation include taking a contiguous slice (subset) of an array, filtering an array using a predicate function, and mapping an array to a parallel set of values using a transform function. Before looking at the set of utilities that D3 provides for arrays, you should familiarize yourself with the powerful [array methods built-in to JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype). | ||
When using D3—and with data in general—you tend to do a lot of array manipulation. Some common forms of array manipulation include taking a contiguous slice (subset) of an array, filtering an array using a predicate function, and mapping an array to a parallel set of values using a transform function. Before looking at the set of utilities that D3 provides for arrays, you should familiarize yourself with the powerful [array methods built-in to JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype). | ||
@@ -36,8 +36,8 @@ JavaScript includes **mutator methods** that modify the array: | ||
Changes from D3 3.x: | ||
## Installing | ||
* The [range](#range) method now returns the empty array for infinite ranges, rather than throwing an error. | ||
* The map and set classes have been removed. Please use ES6 Map and Set instead. | ||
* The [nest.map](#nest_map) method now always returns an ES6 Map. | ||
If you use NPM, `npm install d3-arrays`. Otherwise, download the [latest release](https://github.com/d3/d3-arrays/releases/latest). | ||
## API Reference | ||
<a name="ascending" href="#ascending">#</a> <b>ascending</b>(<i>a</i>, <i>b</i>) | ||
@@ -168,4 +168,9 @@ | ||
Generates an array containing an arithmetic progression, similar to the Python built-in [range](http://docs.python.org/library/functions.html#range). This method is often used to iterate over a sequence of numeric or integer values, such as the indexes into an array. Unlike the Python version, the arguments are not required to be integers, though the results are more predictable if they are due to floating point precision. | ||
Generates an array containing an arithmetic progression, similar to the Python built-in [range](http://docs.python.org/library/functions.html#range). This method is often used to iterate over a sequence of numeric or integer values, such as the indexes into an array. Unlike the Python version, the arguments are not required to be integers, though the results are more predictable if they are due to floating point precision. If the generated array is required to have a specific length, consider using [array.map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) on an integer range. For example: | ||
```js | ||
range(0, 1, 1/49); // BAD: returns 50 elements! | ||
range(49).map(function(d) { return d / 49; }); // GOOD: returns 49 elements. | ||
``` | ||
If *step* is omitted, it defaults to 1. If *start* is omitted, it defaults to 0. The *stop* value is not included in the result. The full form returns an array of numbers [*start*, *start* + *step*, *start* + 2 \* *step*, …]. If *step* is positive, the last element is the largest *start* + *i* \* *step* less than *stop*; if *step* is negative, the last element is the smallest *start* + *i* \* *step* greater than *stop*. If the returned array would contain an infinite number of values, an empty range is returned. | ||
@@ -184,3 +189,3 @@ | ||
console.log(permute(object, fields)); // ["University Farm", "Manchuria", 27] | ||
permute(object, fields); // returns ["University Farm", "Manchuria", 27] | ||
``` | ||
@@ -210,6 +215,8 @@ | ||
### Associative Arrays | ||
### Collections | ||
Another common data type in JavaScript is the associative array, or more simply the object, which has a set of named properties. In Java this is referred to as a map, and in Python, a dictionary. JavaScript provides a standard mechanism for iterating over the keys (or property names) in an associative array: the [for…in loop](https://developer.mozilla.org/en/JavaScript/Reference/Statements/for...in). However, note that the iteration order is undefined. D3 provides several operators for converting associative arrays to standard indexed arrays. | ||
Another common data type in JavaScript is the associative array, or more simply the object, which has a set of named properties. Java refers to this as a *map*, and Python a *dictionary*. JavaScript provides a standard mechanism for iterating over the keys (or property names) in an associative array: the [for…in loop](https://developer.mozilla.org/en/JavaScript/Reference/Statements/for...in). However, note that the iteration order is undefined. D3 provides several operators for converting associative arrays to standard arrays with numeric indexes. | ||
A word of caution: it is tempting to use plain objects as maps, but this causes [unexpected behavior](http://www.devthought.com/2012/01/18/an-object-is-not-a-hash/) when built-in property names are used as keys, such as `object["__proto__"] = 42` and `"hasOwnProperty" in object`. (ES6 introduces Map and Set collections which avoid this problem, but browser support is limited.) If you cannot guarantee that map keys and set values will be safe, you should use [map](#map) and [set](#set) instead of plain objects. | ||
<a name="keys" href="#keys">#</a> <b>keys</b>(<i>object</i>) | ||
@@ -231,2 +238,95 @@ | ||
<a name="map" href="#map">#</a> <b>map</b>([<i>object</i>[, <i>key</i>]]) | ||
Constructs a new map. If *object* is specified, copies all enumerable properties from the specified object into this map. The specified object may also be an array or another map. An optional *key* function may be specified to compute the key for each value in the array. For example: | ||
```js | ||
var m = map([{name: "foo"}, {name: "bar"}], function(d) { return d.name; }); | ||
m.get("foo"); // {"name": "foo"} | ||
m.get("bar"); // {"name": "bar"} | ||
m.get("baz"); // undefined | ||
``` | ||
Note: unlike ES6 Map, D3’s map coerces keys to strings. | ||
See also [nest](#nest). | ||
<a name="map_has" href="#map_has">#</a> map.<b>has</b>(<i>key</i>) | ||
Returns true if and only if this map has an entry for the specified *key* string. Note: the value may be `null` or `undefined`. | ||
<a name="map_get" href="#map_get">#</a> map.<b>get</b>(<i>key</i>) | ||
Returns the value for the specified *key* string. If the map does not have an entry for the specified *key*, returns `undefined`. | ||
<a name="map_set" href="#map_set">#</a> map.<b>set</b>(<i>key</i>, <i>value</i>) | ||
Sets the *value* for the specified *key* string; returns the new *value*. If the map previously had an entry for the same *key* string, the old entry is replaced with the new value. | ||
<a name="map_remove" href="#map_remove">#</a> map.<b>remove</b>(<i>key</i>) | ||
If the map has an entry for the specified *key* string, removes the entry and returns true. Otherwise, this method does nothing and returns false. | ||
<a name="map_keys" href="#map_keys">#</a> map.<b>keys</b>() | ||
Returns an array of string keys for every entry in this map. The order of the returned keys is arbitrary. | ||
<a name="map_values" href="#map_values">#</a> map.<b>values</b>() | ||
Returns an array of values for every entry in this map. The order of the returned values is arbitrary. | ||
<a name="map_entries" href="#map_entries">#</a> map.<b>entries</b>() | ||
Returns an array of key-value objects for each entry in this map. The order of the returned entries is arbitrary. Each entry’s key is a string, but the value has arbitrary type. | ||
<a name="map_forEach" href="#map_forEach">#</a> map.<b>forEach</b>(<i>function</i>) | ||
Calls the specified *function* for each entry in this map, passing the entry's key and value as two arguments. The `this` context of the *function* is this map. Returns undefined. The iteration order is arbitrary. | ||
<a name="map_empty" href="#map_empty">#</a> map.<b>empty</b>() | ||
Returns true if and only if this map has zero entries. | ||
<a name="map_size" href="#map_size">#</a> map.<b>size</b>() | ||
Returns the number of entries in this map. | ||
<a name="set" href="#set">#</a> <b>set</b>([<i>array</i>]) | ||
Constructs a new set. If *array* is specified, adds the given *array* of string values to the returned set. | ||
Note: unlike ES6 Set, D3’s set coerces values to strings. | ||
<a name="set_has" href="#set_has">#</a> set.<b>has</b>(<i>value</i>) | ||
Returns true if and only if this set has an entry for the specified *value* string. | ||
<a name="set_add" href="#set_add">#</a> set.<b>add</b>(<i>value</i>) | ||
Adds the specified *value* string to this set. Returns *value*. | ||
<a name="set_remove" href="#set_remove">#</a> set.<b>remove</b>(<i>value</i>) | ||
If the set contains the specified *value* string, removes it and returns true. Otherwise, this method does nothing and returns false. | ||
<a name="set_values" href="#set_values">#</a> set.<b>values</b>() | ||
Returns an array of the string values in this set. The order of the returned values is arbitrary. Can be used as a convenient way of computing the unique values for a set of strings. For example: | ||
```js | ||
set(["foo", "bar", "foo", "baz"]).values(); // "foo", "bar", "baz" | ||
``` | ||
<a name="set_forEach" href="#set_forEach">#</a> set.<b>forEach</b>(<i>function</i>) | ||
Calls the specified *function* for each value in this set, passing the value as an argument. The `this` context of the *function* is this set. Returns undefined. The iteration order is arbitrary. | ||
<a name="set_empty" href="#set_empty">#</a> set.<b>empty</b>() | ||
Returns true if and only if this set has zero values. | ||
<a name="set_size" href="#set_size">#</a> set.<b>size</b>() | ||
Returns the number of values in this set. | ||
### Nest | ||
@@ -279,3 +379,3 @@ | ||
Creates a new nest operator. The set of keys is initially empty. If the [map](#nest_map) or [entries](#nest_entries) operator is invoked before any key functions are registered, the nest operator simply returns the input array. Examples of nest: [http://bl.ocks.org/phoebebright/raw/3176159/](http://bl.ocks.org/phoebebright/raw/3176159/) | ||
Creates a new nest operator. The set of keys is initially empty. If the [map](#nest_map) or [entries](#nest_entries) operator is invoked before any key functions are registered, the nest operator simply returns the input array. | ||
@@ -307,6 +407,17 @@ <a name="nest_key" href="#nest_key">#</a> nest.<b>key</b>(<i>function</i>) | ||
Applies the nest operator to the specified *array*, returning a map. Each entry in the returned associative array corresponds to a distinct key value returned by the first key function. The entry value depends on the number of registered key functions: if there is an additional key, the value is another nested associative array; otherwise, the value is the array of elements filtered from the input *array* that have the given key value. | ||
Applies the nest operator to the specified *array*, returning a nested [map](#map). Each entry in the returned map corresponds to a distinct key value returned by the first key function. The entry value depends on the number of registered key functions: if there is an additional key, the value is another map; otherwise, the value is the array of elements filtered from the input *array* that have the given key value. | ||
<a name="nest_object" href="#nest_object">#</a> nest.<b>object</b>(<i>array</i>) | ||
Applies the nest operator to the specified *array*, returning a nested object. Each entry in the returned associative array corresponds to a distinct key value returned by the first key function. The entry value depends on the number of registered key functions: if there is an additional key, the value is another associative array; otherwise, the value is the array of elements filtered from the input *array* that have the given key value. | ||
Note: this method is unsafe if any of the keys conflict with built-in JavaScript properties, such as `__proto__`. If you cannot guarantee that the keys will be safe, you should use [nest.map](#nest_map) instead. | ||
<a name="nest_entries" href="#nest_entries">#</a> nest.<b>entries</b>(<i>array</i>) | ||
Applies the nest operator to the specified *array*, returning an array of key-values entries. Conceptually, this is similar to applying [entries](#entries) to the associative array returned by [map](#nest_map), but it applies to every level of the hierarchy rather than just the first (outermost) level. Each entry in the returned array corresponds to a distinct key value returned by the first key function. The entry value depends on the number of registered key functions: if there is an additional key, the value is another nested array of entries; otherwise, the value is the array of elements filtered from the input *array* that have the given key value. | ||
## Changes from D3 3.x: | ||
* The [range](#range) method now returns the empty array for infinite ranges, rather than throwing an error. | ||
* The [nest.map](#nest_map) method now always returns a [map](#map); use [nest.object](#nest_object) to return a plain object instead. |
@@ -0,1 +1,3 @@ | ||
import map from "./map"; | ||
export default function() { | ||
@@ -8,3 +10,3 @@ var keys = [], | ||
function map(array, depth) { | ||
function apply(array, depth, createResult, setResult) { | ||
if (depth >= keys.length) return rollup | ||
@@ -20,4 +22,5 @@ ? rollup.call(nest, array) : (sortValues | ||
value, | ||
valuesByKey = new Map, | ||
values; | ||
valuesByKey = map(), | ||
values, | ||
result = createResult(); | ||
@@ -32,7 +35,7 @@ while (++i < n) { | ||
valuesByKey.forEach(function(values, key) { | ||
valuesByKey.set(key, map(values, depth)); | ||
valuesByKey.forEach(function(key, values) { | ||
setResult(result, key, apply(values, depth, createResult, setResult)); | ||
}); | ||
return valuesByKey; | ||
return result; | ||
} | ||
@@ -43,8 +46,7 @@ | ||
var array = new Array(map.size), | ||
i = -1, | ||
var array = [], | ||
sortKey = sortKeys[depth++]; | ||
map.forEach(function(value, key) { | ||
array[++i] = {key: key, values: entries(value, depth)}; | ||
map.forEach(function(key, value) { | ||
array.push({key: key, values: entries(value, depth)}); | ||
}); | ||
@@ -58,4 +60,5 @@ | ||
return nest = { | ||
map: function(array) { return map(array, 0); }, | ||
entries: function(array) { return entries(map(array, 0), 0); }, | ||
object: function(array) { return apply(array, 0, createObject, setObject); }, | ||
map: function(array) { return apply(array, 0, createMap, setMap); }, | ||
entries: function(array) { return entries(apply(array, 0, createMap, setMap), 0); }, | ||
key: function(d) { keys.push(d); return nest; }, | ||
@@ -67,1 +70,17 @@ sortKeys: function(order) { sortKeys[keys.length - 1] = order; return nest; }, | ||
}; | ||
function createObject() { | ||
return {}; | ||
} | ||
function setObject(object, key, value) { | ||
object[key] = value; | ||
} | ||
function createMap() { | ||
return map(); | ||
} | ||
function setMap(map, key, value) { | ||
map.set(key, value); | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
65608
34
955
416