From e585021586f4b677d470e183af95082cfac71125 Mon Sep 17 00:00:00 2001 From: Wert_Lex Date: Mon, 24 Aug 2015 15:41:04 +0300 Subject: [PATCH] include utils add. Tests ported to should.js --- lib/include_utils.js | 58 ++++++++++++++++++++++++++++++++++++ test/include_util.test.js | 62 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 lib/include_utils.js create mode 100644 test/include_util.test.js diff --git a/lib/include_utils.js b/lib/include_utils.js new file mode 100644 index 00000000..5d1dd1e5 --- /dev/null +++ b/lib/include_utils.js @@ -0,0 +1,58 @@ +module.exports.buildOneToOneIdentityMap = buildOneToOneIdentityMap; +module.exports.buildOneToManyIdentityMap = buildOneToManyIdentityMap; +module.exports.join = join; +/** + * Effectivly builds associative map on id -> object relation. + * Map returned in form of object with ids in keys and object as values. + * @param objs array of objects to build from + * @param idName name of property to be used as id. Such property considered to be unique across array. + * In case of collisions last wins. For non-unique ids use buildOneToManyIdentityMap() + * @returns {{}} object where keys are ids and values are objects itself + */ +function buildOneToOneIdentityMap(objs, idName) { + var idMap = {}; + for(var i = 0; i < objs.length; i++) { + var obj = objs[i]; + var id = obj[idName].toString(); + idMap[id] = obj; + } + return idMap; +} + +/** + * Effectively builds associate map on id -> Array[Object]. + * Map returned in form of object with ids in keys and array of objects with given id. + * @param objs array of objects to build from + * @param idName name of property to be used as id + */ +function buildOneToManyIdentityMap(objs, idName) { + var idMap = {}; + for(var i = 0; i < objs.length; i++) { + var obj = objs[i]; + var id = obj[idName].toString(); + if(id in idMap) { + idMap[id].push(obj); + } else { + idMap[id] = [obj]; + } + } + return idMap; +} + + +/** + * Yeah, it joins. You need three things id -> obj1 map, id -> [obj2] map and merge function. + * This functions will take each obj1, locate all data to join in map2 and call merge function. + * @param oneToOneIdMap + * @param oneToManyIdMap + * @param mergeF function(obj, objectsToMergeIn) + */ +function join(oneToOneIdMap, oneToManyIdMap, mergeF) { + var ids = Object.keys(oneToOneIdMap); + for(var i = 0; i < ids.length; i++) { + var id = ids[i]; + var obj = oneToOneIdMap[id]; + var objectsToMergeIn = oneToManyIdMap[id] || []; + mergeF(obj, objectsToMergeIn); + } +} diff --git a/test/include_util.test.js b/test/include_util.test.js new file mode 100644 index 00000000..bf3af4af --- /dev/null +++ b/test/include_util.test.js @@ -0,0 +1,62 @@ +var assert = require("assert"); +var should = require("should"); + +var includeUtils = require("../lib/include_utils"); + +describe('include_util', function(){ + describe('#buildOneToOneIdentityMap', function(){ + it('should return an object with keys', function(){ + var objs = [ + {id: 11, letter: "A"}, + {id: 22, letter: "B"} + ]; + var result = includeUtils.buildOneToOneIdentityMap(objs, "id"); + result.should.be.an.instanceOf(Object); + result.should.have.property("11"); + result.should.have.property("22"); + }); + + it('should overwrite keys in case of collision', function(){ + var objs = [ + {id: 11, letter: "A"}, + {id: 22, letter: "B"}, + {id: 33, letter: "C"}, + {id: 11, letter: "HA!"} + ]; + + var result = includeUtils.buildOneToOneIdentityMap(objs, "id"); + result.should.be.an.instanceOf(Object); + result.should.have.keys("11", "22", "33"); + result["11"]["letter"].should.equal("HA!"); + result["33"]["letter"].should.equal("C"); + }); + }); + + describe('#buildOneToManyIdentityMap', function(){ + it('should return an object with keys', function(){ + var objs = [ + {id: 11, letter: "A"}, + {id: 22, letter: "B"} + ]; + var result = includeUtils.buildOneToManyIdentityMap(objs, "id"); + result.should.be.an.instanceOf(Object); + result.should.have.keys("11", "22"); + }); + + it('should collect keys in case of collision', function(){ + var objs = [ + {fk_id: 11, letter: "A"}, + {fk_id: 22, letter: "B"}, + {fk_id: 33, letter: "C"}, + {fk_id: 11, letter: "HA!"} + ]; + + var result = includeUtils.buildOneToManyIdentityMap(objs, "fk_id"); + result.should.be.an.instanceOf(Object); + result.should.have.keys("11", "22", "33"); + result["11"][0]["letter"].should.equal("A"); + result["11"][1]["letter"].should.equal("HA!"); + result["33"][0]["letter"].should.equal("C"); + }); + }); +});