map-filter-reduce
Advanced tools
Comparing version 2.1.1 to 2.2.0
@@ -29,3 +29,2 @@ | ||
if(!Array.isArray(a)) a = [a] | ||
if(b == undefined) return a | ||
a.push(b) | ||
@@ -35,1 +34,2 @@ return a | ||
} | ||
@@ -45,3 +45,3 @@ var u = require('./util') | ||
if(u.isObject(q)) return obj(map(q, make)) | ||
throw new Error('no match - should never mappen') | ||
throw new Error('no match - should never happen') | ||
} | ||
@@ -48,0 +48,0 @@ |
{ | ||
"name": "map-filter-reduce", | ||
"description": "", | ||
"version": "2.1.1", | ||
"version": "2.2.0", | ||
"homepage": "https://github.com/dominictarr/map-filter-reduce", | ||
@@ -13,3 +13,4 @@ "repository": { | ||
"pull-sink-through": "0.0.0", | ||
"pull-stream": "^3.2.0" | ||
"pull-stream": "^3.3.0", | ||
"typewiselite": "^1.0.0" | ||
}, | ||
@@ -16,0 +17,0 @@ "devDependencies": { |
var u = require('./util') | ||
var map = u.map | ||
var Map = require('./map') | ||
var simple = require('./basic') | ||
var search = require('binary-search') | ||
var compare = require('typewiselite') | ||
@@ -21,6 +22,9 @@ function isFunction (f) { return 'function' === typeof f } | ||
function multi(obj) { | ||
function multi(query) { | ||
if(u.isFunction(query)) return query | ||
return function (a, b) { | ||
return map(obj, function (reduce, k) { | ||
return reduce(a[k], b) | ||
return u.map(query, function traverse (reduce, k) { | ||
//some reduce functions may be maps (which take one arg) | ||
return reduce.length == 1 ? reduce(b) : reduce(a[k], b) | ||
}, a = a || {}) | ||
@@ -30,9 +34,12 @@ } | ||
function arrayGroup (g, reduce) { | ||
//rawpaths, reducedpaths, reduce | ||
function arrayGroup (_g, g, reduce) { | ||
function compare (a, b) { | ||
for(var i in g) { | ||
var x = u.get(a, g[i]) | ||
var y = u.get(b, g[i]) | ||
if(x != y) return x < y ? -1 : 1 | ||
//we can use a different lookup path on the right hand object | ||
//is always the "needle" | ||
//compare(haystay[j], needle) | ||
function _compare (hay, needle) { | ||
for(var i in _g) { | ||
var x = u.get(hay, _g[i]), y = needle[i] | ||
if(x !== y) return compare(x, y) // < y ? -1 : 1 | ||
} | ||
@@ -43,4 +50,5 @@ return 0 | ||
return function (a, b) { | ||
if(a && !Array.isArray(a)) a = reduce([], a) | ||
var A = a = a || [] | ||
var i = search(A, b, compare) | ||
var i = search(A, g.map(function (fn) { return fn(b) }), _compare) | ||
@@ -68,2 +76,13 @@ if(i >= 0) A[i] = reduce(A[i], b) | ||
function make2 (query) { | ||
var r = isSimple(query) | ||
if(r) return r | ||
if(query.$group) | ||
return objectGroup(query.$group, multi(make2(query.$reduce))) | ||
if(query.$reduce) | ||
return make2(query.$reduce) | ||
if(u.isObject(query)) | ||
return u.map(query, make2) | ||
return Map(query) | ||
} | ||
@@ -75,25 +94,27 @@ function make (query) { | ||
return objectGroup(query.$group, gmake(query.$reduce)) | ||
else if(u.isObject(query)) { | ||
return multi(map(query, gmake)) | ||
else if(u.isObject(query) && !u.isArray(query)) { | ||
return multi(u.map(query, gmake)) | ||
} | ||
else return function (a, b) { | ||
return b[query] | ||
return u.get(b, query) | ||
} | ||
} | ||
function amake (query) { | ||
if(query.$group) return objectGroup(query.$group, make(query.$reduce)) | ||
var _query = make2(query) | ||
if(query.$group) | ||
return objectGroup(query.$group, make(query.$reduce)) | ||
var r = isSimple(query) | ||
if(r) return r | ||
//get the lookup paths, and the paths they will be saved to. | ||
//these will both be passed to arrayGroup. | ||
var paths = [] | ||
u.each(query, function traverse (value) { | ||
if(isSimple(value) || value.$group || value.$reduce) return | ||
else if(u.isObject(value)) each(value, traverse) | ||
else if(value) paths.push(value) | ||
var _paths = u.paths(_query, function (value) { | ||
if(u.isFunction(value) && value.length === 1) { | ||
return paths.push(value), true | ||
} | ||
}) | ||
return paths.length ? arrayGroup(paths, make(query)) : make(query) | ||
return paths.length ? arrayGroup(_paths, paths, make(query)) : make(query) | ||
} | ||
@@ -108,1 +129,4 @@ | ||
@@ -40,3 +40,3 @@ | ||
t.deepEqual(map('key', 'string'), undefined) | ||
t.deepEqual(map({foo: true}, {bar:1, baz:2}), undefined) | ||
t.deepEqual(map({foo: true}, {bar:1, baz:2}), {foo: undefined}) | ||
t.deepEqual(map({foo: true}, null), undefined) | ||
@@ -43,0 +43,0 @@ t.deepEqual(map(['a', 'b', 'c'], {a: true}), undefined) |
var tape = require('tape') | ||
var project = require('../util').project | ||
var paths = require('../util').paths | ||
var u = require('../util') | ||
var project = u.project | ||
var paths = u.paths | ||
@@ -40,5 +41,29 @@ var input = { | ||
function truth (e) { return e === true } | ||
function untruth (e) { return e === false } | ||
function not(fn) { | ||
return function (v) { return !fn(v) } | ||
} | ||
var input2 = { | ||
foo: {bar: true, baz: false}, | ||
baz: false, | ||
foofoo: {whatever: false, okay: true}, | ||
numbers: [1,2,3] | ||
} | ||
tape('paths', function (t) { | ||
t.deepEqual(paths(input, function (e) { return e===true }), [['foo', 'bar'], ['foofoo', 'okay']]) | ||
t.deepEqual(paths(input2, truth), [['foo', 'bar'], ['foofoo', 'okay']]) | ||
t.deepEqual(paths(input2, untruth), [['foo', 'baz'],'baz', ['foofoo', 'whatever']]) | ||
t.deepEqual(paths(input2, u.isObject), []) | ||
t.deepEqual(paths(input2, u.isBasic), [ | ||
[ 'foo', 'bar' ], [ 'foo', 'baz' ], 'baz', | ||
[ 'foofoo', 'whatever' ], [ 'foofoo', 'okay' ] ] | ||
) | ||
t.deepEqual(paths({okay: true}, truth), ['okay']) | ||
t.deepEqual(paths({okay: true}, untruth), []) | ||
t.end() | ||
}) | ||
@@ -15,6 +15,6 @@ var tape = require('tape') | ||
var objs = [ | ||
{foo: 0, bar: 1, baz: false}, | ||
{foo: 10, bar: 2, baz: true}, | ||
{foo: 0, bar: 1, baz: false, other: 'sometimes'}, | ||
{foo: 10, bar: 2, baz: true, other: true}, | ||
{foo: -5, bar: 3, baz: true}, | ||
{foo: -5, bar: 4, baz: false}, | ||
{foo: -5, bar: 4, baz: false, other: {okay: true}}, | ||
{foo: 3, bar: 5, baz: true} | ||
@@ -84,2 +84,18 @@ ] | ||
tape('group, sometimes', function (t) { | ||
t.deepEqual( | ||
objs.reduce(R({ | ||
other: ['other', 'okay'], | ||
values: {$collect: 'other'} | ||
}), null), | ||
[ | ||
{other: true, values: [{okay: true}]}, | ||
{other: undefined, values: ['sometimes', true, undefined, undefined]} | ||
] | ||
) | ||
t.end() | ||
}) | ||
var groups = [ | ||
@@ -86,0 +102,0 @@ { |
27
util.js
'use strict' | ||
function isString(s) { return 'string' === typeof s } | ||
@@ -10,5 +11,7 @@ | ||
function isFunction (f) { return 'function' === typeof f } | ||
var isArray = Array.isArray | ||
function isObject (o) { return o && 'object' === typeof o } | ||
function isObject (o) { return o && 'object' === typeof o && !isArray(o) } | ||
@@ -81,7 +84,17 @@ function has(o, k) { | ||
o = o || {} | ||
for(var k in obj) | ||
o[k] = iter(obj[k], k, obj) | ||
return o | ||
} | ||
function mapa(obj, iter) { | ||
if(Array.isArray(obj)) return obj.map(iter) | ||
var a = [] | ||
for(var k in obj) { | ||
var v = iter(obj[k], k, obj) | ||
if(v !== undefined) o[k] = v | ||
if(v !== undefined) a.push(v) | ||
} | ||
return o | ||
return a | ||
} | ||
@@ -116,2 +129,3 @@ | ||
var p = [] | ||
if(test(object)) return [] | ||
for(var key in object) { | ||
@@ -136,2 +150,3 @@ var value = object[key] | ||
exports.isLtgt = isLtgt | ||
exports.isFunction = isFunction | ||
@@ -141,2 +156,3 @@ exports.has = has | ||
exports.map = map | ||
exports.mapa = mapa | ||
exports.project = project | ||
@@ -152,1 +168,6 @@ exports.paths = paths | ||
30861
19
919
4
+ Addedtypewiselite@^1.0.0
+ Addedtypewiselite@1.0.0(transitive)
Updatedpull-stream@^3.3.0