multimap
Advanced tools
Comparing version 0.0.2 to 0.1.0
288
index.js
"use strict"; | ||
module.exports = Multimap; | ||
/* global module, define */ | ||
function Multimap(iterable) { | ||
var self = this; | ||
if (Multimap.Map) { | ||
self._map = Multimap.Map; | ||
var Multimap = (function() { | ||
var mapCtor; | ||
if (typeof Map !== 'undefined') { | ||
mapCtor = Map; | ||
} | ||
self._ = self._map ? new self._map() : {}; | ||
function Multimap(iterable) { | ||
var self = this; | ||
if (iterable) { | ||
iterable.forEach(function(i) { | ||
self.set(i[0], i[1]); | ||
}); | ||
self._map = mapCtor; | ||
if (Multimap.Map) { | ||
self._map = Multimap.Map; | ||
} | ||
self._ = self._map ? new self._map() : {}; | ||
if (iterable) { | ||
iterable.forEach(function(i) { | ||
self.set(i[0], i[1]); | ||
}); | ||
} | ||
} | ||
} | ||
/** | ||
* @param {Object} key | ||
* @return {Array} An array of values, undefined if no such a key; | ||
*/ | ||
Multimap.prototype.get = function(key) { | ||
return this._map ? this._.get(key) : this._[key]; | ||
}; | ||
/** | ||
* @param {Object} key | ||
* @return {Array} An array of values, undefined if no such a key; | ||
*/ | ||
Multimap.prototype.get = function(key) { | ||
return this._map ? this._.get(key) : this._[key]; | ||
}; | ||
/** | ||
* @param {Object} key | ||
* @param {Object} val... | ||
*/ | ||
Multimap.prototype.set = function(key, val) { | ||
var args = Array.prototype.slice.call(arguments); | ||
/** | ||
* @param {Object} key | ||
* @param {Object} val... | ||
*/ | ||
Multimap.prototype.set = function(key, val) { | ||
var args = Array.prototype.slice.call(arguments); | ||
key = args.shift(); | ||
key = args.shift(); | ||
var entry = this.get(key); | ||
if (!entry) { | ||
entry = []; | ||
if (this._map) | ||
this._.set(key, entry); | ||
else | ||
this._[key] = entry; | ||
} | ||
var entry = this.get(key); | ||
if (!entry) { | ||
entry = []; | ||
if (this._map) | ||
this._.set(key, entry); | ||
else | ||
this._[key] = entry; | ||
} | ||
Array.prototype.push.apply(entry, args); | ||
return this; | ||
}; | ||
Array.prototype.push.apply(entry, args); | ||
return this; | ||
}; | ||
/** | ||
* @param {Object} key | ||
* @param {Object=} val | ||
* @return {boolean} true if any thing changed | ||
*/ | ||
Multimap.prototype.delete = function(key, val) { | ||
if (!this.has(key)) | ||
return false; | ||
/** | ||
* @param {Object} key | ||
* @param {Object=} val | ||
* @return {boolean} true if any thing changed | ||
*/ | ||
Multimap.prototype.delete = function(key, val) { | ||
if (!this.has(key)) | ||
return false; | ||
if (arguments.length == 1) { | ||
this._map ? (this._.delete(key)) : (delete this._[key]); | ||
return true; | ||
} else { | ||
var entry = this.get(key); | ||
var idx = entry.indexOf(val); | ||
if (idx != -1) { | ||
entry.splice(idx, 1); | ||
if (arguments.length == 1) { | ||
this._map ? (this._.delete(key)) : (delete this._[key]); | ||
return true; | ||
} else { | ||
var entry = this.get(key); | ||
var idx = entry.indexOf(val); | ||
if (idx != -1) { | ||
entry.splice(idx, 1); | ||
return true; | ||
} | ||
} | ||
} | ||
return false; | ||
}; | ||
return false; | ||
}; | ||
/** | ||
* @param {Object} key | ||
* @param {Object=} val | ||
* @return {boolean} whether the map contains 'key' or 'key=>val' pair | ||
*/ | ||
Multimap.prototype.has = function(key, val) { | ||
var hasKey = this._map ? this._.has(key) : this._.hasOwnProperty(key); | ||
/** | ||
* @param {Object} key | ||
* @param {Object=} val | ||
* @return {boolean} whether the map contains 'key' or 'key=>val' pair | ||
*/ | ||
Multimap.prototype.has = function(key, val) { | ||
var hasKey = this._map ? this._.has(key) : this._.hasOwnProperty(key); | ||
if (arguments.length == 1 || !hasKey) | ||
return hasKey; | ||
if (arguments.length == 1 || !hasKey) | ||
return hasKey; | ||
var entry = this.get(key) || []; | ||
return entry.indexOf(val) != -1; | ||
}; | ||
var entry = this.get(key) || []; | ||
return entry.indexOf(val) != -1; | ||
}; | ||
/** | ||
* @return {Array} all the keys in the map | ||
*/ | ||
Multimap.prototype.keys = function() { | ||
if (this._map) | ||
return this._.keys(); | ||
/** | ||
* @return {Array} all the keys in the map | ||
*/ | ||
Multimap.prototype.keys = function() { | ||
if (this._map) | ||
return this._.keys(); | ||
return makeIterator(Object.keys(this._)); | ||
}; | ||
return makeIterator(Object.keys(this._)); | ||
}; | ||
/** | ||
* @return {Array} all the values in the map | ||
*/ | ||
Multimap.prototype.values = function() { | ||
var vals = []; | ||
this.forEachEntry(function(entry) { | ||
Array.prototype.push.apply(vals, entry); | ||
}); | ||
/** | ||
* @return {Array} all the values in the map | ||
*/ | ||
Multimap.prototype.values = function() { | ||
var vals = []; | ||
this.forEachEntry(function(entry) { | ||
Array.prototype.push.apply(vals, entry); | ||
}); | ||
return makeIterator(vals); | ||
}; | ||
return makeIterator(vals); | ||
}; | ||
/** | ||
* | ||
*/ | ||
Multimap.prototype.forEachEntry = function(iter) { | ||
var self = this; | ||
/** | ||
* | ||
*/ | ||
Multimap.prototype.forEachEntry = function(iter) { | ||
var self = this; | ||
var keys = self.keys(); | ||
var next; | ||
while(!(next = keys.next()).done) { | ||
iter(self.get(next.value), next.value, self); | ||
} | ||
}; | ||
var keys = self.keys(); | ||
var next; | ||
while(!(next = keys.next()).done) { | ||
iter(self.get(next.value), next.value, self); | ||
} | ||
}; | ||
Multimap.prototype.forEach = function(iter) { | ||
var self = this; | ||
self.forEachEntry(function(entry, key) { | ||
entry.forEach(function(item) { | ||
iter(item, key, self); | ||
Multimap.prototype.forEach = function(iter) { | ||
var self = this; | ||
self.forEachEntry(function(entry, key) { | ||
entry.forEach(function(item) { | ||
iter(item, key, self); | ||
}); | ||
}); | ||
}); | ||
}; | ||
}; | ||
Multimap.prototype.clear = function() { | ||
if (this._map) { | ||
this._.clear(); | ||
} else { | ||
this._ = {}; | ||
} | ||
}; | ||
Multimap.prototype.clear = function() { | ||
if (this._map) { | ||
this._.clear(); | ||
} else { | ||
this._ = {}; | ||
} | ||
}; | ||
Object.defineProperty( | ||
Multimap.prototype, | ||
"size", { | ||
configurable: false, | ||
enumerable: true, | ||
get: function() { | ||
var self = this; | ||
var keys = self.keys(); | ||
var next, total = 0; | ||
while(!(next = keys.next()).done) { | ||
total += self.get(next.value).length; | ||
Object.defineProperty( | ||
Multimap.prototype, | ||
"size", { | ||
configurable: false, | ||
enumerable: true, | ||
get: function() { | ||
var self = this; | ||
var keys = self.keys(); | ||
var next, total = 0; | ||
while(!(next = keys.next()).done) { | ||
total += self.get(next.value).length; | ||
} | ||
return total; | ||
} | ||
return total; | ||
} | ||
}); | ||
}); | ||
function makeIterator(array){ | ||
var nextIndex = 0; | ||
return { | ||
next: function(){ | ||
return nextIndex < array.length ? | ||
{value: array[nextIndex++], done: false} : | ||
{done: true}; | ||
} | ||
}; | ||
} | ||
function makeIterator(array){ | ||
var nextIndex = 0; | ||
return { | ||
next: function(){ | ||
return nextIndex < array.length ? | ||
{value: array[nextIndex++], done: false} : | ||
{done: true}; | ||
} | ||
} | ||
} | ||
return Multimap; | ||
})(); | ||
if(typeof exports === 'object' && module && module.exports) | ||
module.exports = Multimap; | ||
else if(typeof define === 'function' && define.amd) | ||
define(function() { return Multimap; }); |
{ | ||
"name": "multimap", | ||
"version": "0.0.2", | ||
"version": "0.1.0", | ||
"description": "multi-map which allow multi values for the same key", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -19,3 +19,3 @@ # Multimap - Map which Allow Multiple Values for the same Key | ||
If `Multimap.Map` is set, `Multimap` will use the `Map` as inner store, that means Object can be used as key. | ||
If the global es6 `Map` exists or `Multimap.Map` is set, `Multimap` will use the `Map` as inner store, that means Object can be used as key. | ||
@@ -26,4 +26,3 @@ ```javascript | ||
// if harmony is on | ||
Multimap.Map = Map; | ||
/* nothing need to do */ | ||
// or if you are using es6-shim | ||
@@ -40,4 +39,29 @@ Multimap.Map = ShimMap; | ||
#### API | ||
### Browser | ||
Just download the `index.js` as `Multimap.js`. | ||
``` | ||
<script src=Multimap.js"></script> | ||
<script> | ||
var map = new Multimap([['a', 1], ['b', 2], ['c', 3]]); | ||
map = map.set('b', 20); | ||
map.get('b'); // [2, 20] | ||
</script> | ||
``` | ||
Or use as an AMD loader: | ||
``` | ||
require(['./Multimap.js'], function (Multimap) { | ||
var map = new Multimap([['a', 1], ['b', 2], ['c', 3]]); | ||
map = map.set('b', 20); | ||
map.get('b'); // [2, 20] | ||
}); | ||
``` | ||
## API | ||
Following shows how to use `Multimap`: | ||
@@ -44,0 +68,0 @@ |
@@ -5,4 +5,4 @@ "use strict"; | ||
require('es6-shim'); | ||
var Multimap = require('..'); | ||
Multimap.Map = Map; | ||
@@ -9,0 +9,0 @@ var map = new Multimap([ |
12690
274
124