2009-03-05 19:56:01 +00:00
|
|
|
|
/** section: Language
|
2008-12-14 04:36:59 +00:00
|
|
|
|
* $H([object]) -> Hash
|
|
|
|
|
*
|
|
|
|
|
* Creates a Hash (which is synonymous to “map” or “associative array” for our purposes).
|
|
|
|
|
* A convenience wrapper around the Hash constructor, with a safeguard that lets you pass
|
|
|
|
|
* an existing Hash object and get it back untouched (instead of uselessly cloning it).
|
|
|
|
|
**/
|
2007-10-13 10:55:52 +00:00
|
|
|
|
function $H(object) {
|
|
|
|
|
return new Hash(object);
|
2007-01-18 22:24:27 +00:00
|
|
|
|
};
|
|
|
|
|
|
2009-03-05 19:56:01 +00:00
|
|
|
|
/** section: Language
|
2008-12-14 04:36:59 +00:00
|
|
|
|
* class Hash
|
|
|
|
|
**/
|
2007-10-13 10:55:52 +00:00
|
|
|
|
var Hash = Class.create(Enumerable, (function() {
|
2008-12-14 04:36:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* new Hash([object])
|
|
|
|
|
*
|
2009-02-24 02:21:02 +00:00
|
|
|
|
* Creates a new `Hash`. If `object` is given, the new hash will be populated
|
|
|
|
|
* with all the object's properties. See [[$H]].
|
2008-12-14 04:36:59 +00:00
|
|
|
|
**/
|
2008-09-28 17:41:53 +00:00
|
|
|
|
function initialize(object) {
|
|
|
|
|
this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function _each(iterator) {
|
|
|
|
|
for (var key in this._object) {
|
|
|
|
|
var value = this._object[key], pair = [key, value];
|
|
|
|
|
pair.key = key;
|
|
|
|
|
pair.value = value;
|
|
|
|
|
iterator(pair);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-14 04:36:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Hash#set(key, value) -> value
|
|
|
|
|
*
|
|
|
|
|
* Sets the hash’s `key` property to value and returns value.
|
|
|
|
|
**/
|
2008-09-28 17:41:53 +00:00
|
|
|
|
function set(key, value) {
|
|
|
|
|
return this._object[key] = value;
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-14 04:36:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Hash#get(key) -> value
|
|
|
|
|
*
|
|
|
|
|
* Returns the value of the hash’s `key` property.
|
|
|
|
|
**/
|
2008-09-28 17:41:53 +00:00
|
|
|
|
function get(key) {
|
|
|
|
|
// simulating poorly supported hasOwnProperty
|
|
|
|
|
if (this._object[key] !== Object.prototype[key])
|
|
|
|
|
return this._object[key];
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-14 04:36:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Hash#unset(key) -> value
|
|
|
|
|
*
|
|
|
|
|
* Deletes the hash’s `key` property and returns its value.
|
|
|
|
|
**/
|
2008-09-28 17:41:53 +00:00
|
|
|
|
function unset(key) {
|
|
|
|
|
var value = this._object[key];
|
|
|
|
|
delete this._object[key];
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-14 04:36:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Hash#toObject() -> Object
|
|
|
|
|
*
|
|
|
|
|
* Returns a cloned, vanilla object.
|
|
|
|
|
**/
|
2008-09-28 17:41:53 +00:00
|
|
|
|
function toObject() {
|
|
|
|
|
return Object.clone(this._object);
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-14 04:36:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Hash#keys() -> [String...]
|
|
|
|
|
*
|
|
|
|
|
* Provides an Array of keys (that is, property names) for the hash.
|
|
|
|
|
**/
|
2008-09-28 17:41:53 +00:00
|
|
|
|
function keys() {
|
|
|
|
|
return this.pluck('key');
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-14 04:36:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Hash#values() -> Array
|
|
|
|
|
*
|
|
|
|
|
* Collect the values of a hash and returns them in an array.
|
|
|
|
|
**/
|
2008-09-28 17:41:53 +00:00
|
|
|
|
function values() {
|
|
|
|
|
return this.pluck('value');
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-14 04:36:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Hash#index(value) -> String
|
|
|
|
|
*
|
2009-02-24 02:21:02 +00:00
|
|
|
|
* Returns the first key in the hash whose value matches `value`.
|
|
|
|
|
* Returns `false` if there is no such key.
|
2008-12-14 04:36:59 +00:00
|
|
|
|
**/
|
2008-09-28 17:41:53 +00:00
|
|
|
|
function index(value) {
|
|
|
|
|
var match = this.detect(function(pair) {
|
|
|
|
|
return pair.value === value;
|
|
|
|
|
});
|
|
|
|
|
return match && match.key;
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-14 04:36:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Hash#merge(object) -> Hash
|
|
|
|
|
*
|
2009-02-24 02:21:02 +00:00
|
|
|
|
* Returns a new hash with `object`'s key/value pairs merged in.
|
|
|
|
|
* To modify the original hash in place, use [[Hash#update]].
|
|
|
|
|
*
|
2008-12-14 04:36:59 +00:00
|
|
|
|
**/
|
2008-09-28 17:41:53 +00:00
|
|
|
|
function merge(object) {
|
|
|
|
|
return this.clone().update(object);
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-14 04:36:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Hash#update(object) -> Hash
|
|
|
|
|
*
|
|
|
|
|
* Updates hash with the key/value pairs of `object`.
|
2009-02-24 02:21:02 +00:00
|
|
|
|
* The original hash will be modified. To return a new hash instead, use
|
|
|
|
|
* [[Hash#merge]].
|
2008-12-14 04:36:59 +00:00
|
|
|
|
**/
|
2008-09-28 17:41:53 +00:00
|
|
|
|
function update(object) {
|
|
|
|
|
return new Hash(object).inject(this, function(result, pair) {
|
|
|
|
|
result.set(pair.key, pair.value);
|
|
|
|
|
return result;
|
|
|
|
|
});
|
|
|
|
|
}
|
2007-11-14 11:56:15 +00:00
|
|
|
|
|
2009-02-24 02:21:02 +00:00
|
|
|
|
// Private. No PDoc necessary.
|
2007-10-13 10:55:52 +00:00
|
|
|
|
function toQueryPair(key, value) {
|
|
|
|
|
if (Object.isUndefined(value)) return key;
|
|
|
|
|
return key + '=' + encodeURIComponent(String.interpret(value));
|
2007-01-18 22:24:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-12-14 04:36:59 +00:00
|
|
|
|
/** related to: String#toQueryParams
|
|
|
|
|
* Hash#toQueryString() -> String
|
|
|
|
|
*
|
|
|
|
|
* Turns a hash into its URL-encoded query string representation.
|
|
|
|
|
**/
|
2008-09-28 17:41:53 +00:00
|
|
|
|
function toQueryString() {
|
|
|
|
|
return this.inject([], function(results, pair) {
|
|
|
|
|
var key = encodeURIComponent(pair.key), values = pair.value;
|
|
|
|
|
|
|
|
|
|
if (values && typeof values == 'object') {
|
|
|
|
|
if (Object.isArray(values))
|
|
|
|
|
return results.concat(values.map(toQueryPair.curry(key)));
|
|
|
|
|
} else results.push(toQueryPair(key, values));
|
|
|
|
|
return results;
|
|
|
|
|
}).join('&');
|
2007-03-09 03:15:03 +00:00
|
|
|
|
}
|
2008-09-28 17:41:53 +00:00
|
|
|
|
|
2008-12-14 04:36:59 +00:00
|
|
|
|
/** related to: Object.inspect
|
|
|
|
|
* Hash#inspect() -> String
|
|
|
|
|
*
|
|
|
|
|
* Returns the debug-oriented string representation of the hash.
|
|
|
|
|
**/
|
2008-09-28 17:41:53 +00:00
|
|
|
|
function inspect() {
|
|
|
|
|
return '#<Hash:{' + this.map(function(pair) {
|
|
|
|
|
return pair.map(Object.inspect).join(': ');
|
|
|
|
|
}).join(', ') + '}>';
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-14 04:36:59 +00:00
|
|
|
|
/** related to: Object.toJSON
|
|
|
|
|
* Hash#toJSON() -> String
|
|
|
|
|
*
|
|
|
|
|
* Returns a JSON string.
|
|
|
|
|
**/
|
2008-09-28 17:41:53 +00:00
|
|
|
|
function toJSON() {
|
|
|
|
|
return Object.toJSON(this.toObject());
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-14 04:36:59 +00:00
|
|
|
|
/**
|
2009-02-24 02:21:02 +00:00
|
|
|
|
* Hash#clone() -> Hash
|
2008-12-14 04:36:59 +00:00
|
|
|
|
*
|
|
|
|
|
* Returns a clone of hash.
|
|
|
|
|
**/
|
2008-09-28 17:41:53 +00:00
|
|
|
|
function clone() {
|
|
|
|
|
return new Hash(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
initialize: initialize,
|
|
|
|
|
_each: _each,
|
|
|
|
|
set: set,
|
|
|
|
|
get: get,
|
|
|
|
|
unset: unset,
|
|
|
|
|
toObject: toObject,
|
|
|
|
|
toTemplateReplacements: toObject,
|
|
|
|
|
keys: keys,
|
|
|
|
|
values: values,
|
|
|
|
|
index: index,
|
|
|
|
|
merge: merge,
|
|
|
|
|
update: update,
|
|
|
|
|
toQueryString: toQueryString,
|
|
|
|
|
inspect: inspect,
|
|
|
|
|
toJSON: toJSON,
|
|
|
|
|
clone: clone
|
|
|
|
|
};
|
2007-10-13 10:55:52 +00:00
|
|
|
|
})());
|
|
|
|
|
|
2007-10-17 13:39:46 +00:00
|
|
|
|
Hash.from = $H;
|