Skip to content

add factory dictionary as requested in #43 #47

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 10, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions dist/lib/FactoryDictionary.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import Dictionary from './Dictionary';
export default class FactoryDictionary<K, V> extends Dictionary<K, V> {
/**
* Factory to create default values.
* @type {function(Object):string}
* @protected
*/
protected defaultFactoryFunction: () => V;
/**
* Creates an empty dictionary.
* @class <p>Dictionaries map keys to values; each key can map to at most one value.
* This implementation accepts any kind of objects as keys.</p>
*
* <p>The default factory function should return a new object of the provided
* type. Example:</p>
* <pre>
* function petFactory() {
* return new Pet();
* }
* </pre>
*
* <p>If the keys are custom objects a function which converts keys to unique
* strings must be provided. Example:</p>
* <pre>
* function petToString(pet) {
* return pet.name;
* }
* </pre>
* @constructor
* @param {function():V=} defaultFactoryFunction function used to create a
* default object.
* @param {function(Object):string=} toStrFunction optional function used
* to convert keys to strings. If the keys aren't strings or if toString()
* is not appropriate, a custom function which receives a key and returns a
* unique string must be provided.
*/
constructor(defaultFactoryFunction: () => V, toStrFunction?: (key: K) => string);
/**
* Associates the specified default value with the specified key in this dictionary,
* if it didn't contain the key yet. If the key existed, the existing value will be used.
* @param {Object} key key with which the specified value is to be
* associated.
* @param {Object} defaultValue default value to be associated with the specified key.
* @return {*} previous value associated with the specified key, or the default value,
* if the key didn't exist yet.
*/
setDefault(key: K, defaultValue: V): V;
/**
* Returns the value to which this dictionary maps the specified key.
* Returns a default value created by the factory passed in the constructor,
* if this dictionary contains no mapping for this key. The missing key will
* automatically be added to the dictionary.
* @param {Object} key key whose associated value is to be returned.
* @return {*} the value to which this dictionary maps the specified key or
* a default value if the map contains no mapping for this key.
*/
getValue(key: K): V;
}
76 changes: 76 additions & 0 deletions dist/lib/FactoryDictionary.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions dist/lib/FactoryDictionary.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions dist/lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export { default as Heap } from './Heap';
export { default as LinkedDictionary } from './LinkedDictionary';
export { default as LinkedList } from './LinkedList';
export { default as MultiDictionary } from './MultiDictionary';
export { default as FactoryDictionary } from './FactoryDictionary';
export { default as Queue } from './Queue';
export { default as PriorityQueue } from './PriorityQueue';
export { default as Set } from './Set';
Expand Down
2 changes: 2 additions & 0 deletions dist/lib/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/lib/index.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

107 changes: 93 additions & 14 deletions dist/lib/umd.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/lib/umd.min.js

Large diffs are not rendered by default.

Empty file.
22 changes: 22 additions & 0 deletions dist/test/factoryDictionaryTest.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions dist/test/factoryDictionaryTest.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/test/utilTest.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/test/utilTest.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

81 changes: 81 additions & 0 deletions src/lib/FactoryDictionary.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import Dictionary from './Dictionary';
import * as util from './util';

export default class FactoryDictionary<K, V> extends Dictionary<K, V> {

/**
* Factory to create default values.
* @type {function(Object):string}
* @protected
*/
protected defaultFactoryFunction: () => V;

/**
* Creates an empty dictionary.
* @class <p>Dictionaries map keys to values; each key can map to at most one value.
* This implementation accepts any kind of objects as keys.</p>
*
* <p>The default factory function should return a new object of the provided
* type. Example:</p>
* <pre>
* function petFactory() {
* return new Pet();
* }
* </pre>
*
* <p>If the keys are custom objects a function which converts keys to unique
* strings must be provided. Example:</p>
* <pre>
* function petToString(pet) {
* return pet.name;
* }
* </pre>
* @constructor
* @param {function():V=} defaultFactoryFunction function used to create a
* default object.
* @param {function(Object):string=} toStrFunction optional function used
* to convert keys to strings. If the keys aren't strings or if toString()
* is not appropriate, a custom function which receives a key and returns a
* unique string must be provided.
*/
constructor(defaultFactoryFunction: () => V, toStrFunction?: (key: K) => string) {
super(toStrFunction);

this.defaultFactoryFunction = defaultFactoryFunction;
}


/**
* Associates the specified default value with the specified key in this dictionary,
* if it didn't contain the key yet. If the key existed, the existing value will be used.
* @param {Object} key key with which the specified value is to be
* associated.
* @param {Object} defaultValue default value to be associated with the specified key.
* @return {*} previous value associated with the specified key, or the default value,
* if the key didn't exist yet.
*/
setDefault(key: K, defaultValue: V): V {
const currentValue: V = super.getValue(key);

if (util.isUndefined(currentValue)) {
this.setValue(key, defaultValue);

return defaultValue;
}

return currentValue;
}

/**
* Returns the value to which this dictionary maps the specified key.
* Returns a default value created by the factory passed in the constructor,
* if this dictionary contains no mapping for this key. The missing key will
* automatically be added to the dictionary.
* @param {Object} key key whose associated value is to be returned.
* @return {*} the value to which this dictionary maps the specified key or
* a default value if the map contains no mapping for this key.
*/
getValue(key: K): V {
return this.setDefault(key, this.defaultFactoryFunction());
}
}
1 change: 1 addition & 0 deletions src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export {default as Heap} from './Heap';
export {default as LinkedDictionary} from './LinkedDictionary';
export {default as LinkedList} from './LinkedList';
export {default as MultiDictionary} from './MultiDictionary';
export {default as FactoryDictionary} from './FactoryDictionary';
export {default as Queue} from './Queue';
export {default as PriorityQueue} from './PriorityQueue';
export {default as Set} from './Set';
Expand Down
34 changes: 34 additions & 0 deletions src/test/factoryDictionaryTest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import * as collections from '../lib/index';

import assert = require('assert');
import {expect} from 'chai';

describe('Factory Dictionary',
function() {

var dict: any = null;
var defaultValue: Array<any> = [];

beforeEach(function() {
dict = new collections.FactoryDictionary(() => []);
});

it('Uses the default value only when necessary',
function() {
expect(dict.setDefault('a', defaultValue)).to.deep.equal(defaultValue);

var key: string = 'b';

dict.setValue(key, []);
expect(dict.setDefault(key, defaultValue)).to.not.equal(defaultValue);
});

it('Automatically creates a key with a default value if it doesn\'t exist',
function() {
var key: string = 'a';

expect(dict.getValue(key)).to.deep.equal(defaultValue);
expect(dict.containsKey(key)).equals(true);
});

});