52 var result =
new CFMutableDictionary();
53 result.isa = [
self class];
62 return [[
self alloc] init];
72 return [[
self alloc] initWithDictionary:aDictionary];
81 + (id)dictionaryWithObject:(
id)anObject forKey:(
id)aKey
93 + (id)dictionaryWithObjects:(CPArray)objects forKeys:(CPArray)keys
103 + (id)dictionaryWithJSObject:(JSObject)object
113 + (id)dictionaryWithJSObject:(JSObject)object recursively:(BOOL)recursively
116 dictionary = [[
self alloc] init];
120 if (!
object.hasOwnProperty(key))
123 var value =
object[key];
133 if (value.constructor === Object)
135 else if ([value isKindOfClass:CPArray])
139 count = value.length;
141 for (; i < count; i++)
143 var thisValue = value[i];
145 if (thisValue === null)
147 newValue.push([
CPNull null]);
151 if (thisValue.constructor === Object)
152 newValue.push([
CPDictionary dictionaryWithJSObject:thisValue recursively:YES]);
154 newValue.push(thisValue);
185 + (id)dictionaryWithObjectsAndKeys:(
id)firstObject, ...
187 arguments[0] = [
self alloc];
188 arguments[1] =
@selector(initWithObjectsAndKeys:);
190 return objj_msgSend.apply(
this, arguments);
203 for (key in aDictionary._buckets)
216 - (id)initWithObjects:(CPArray)objects forKeys:(CPArray)keyArray
220 if ([objects count] != [keyArray count])
225 var i = [keyArray count];
229 var value = objects[i],
233 [
CPException raise:CPInvalidArgumentException
reason:@"Attempt to insert nil object from objects[" + i + @"]"];
259 - (id)initWithObjectsAndKeys:(
id)firstObject, ...
261 var argCount = arguments.length;
263 if (argCount % 2 !== 0)
264 [
CPException raise:CPInvalidArgumentException
reason:"Key-value count is mismatched. (" + argCount + " arguments passed)"];
273 for (; index < argCount; index += 2)
275 var value = arguments[index],
276 key = arguments[index + 1];
279 [
CPException raise:CPInvalidArgumentException
reason:@"Attempt to insert nil object from objects[" + ((index / 2) - 1) + @"]"];
282 [
CPException raise:CPInvalidArgumentException
reason:@"Attempt to insert nil key from keys[" + ((index / 2) - 1) + @"]"];
312 return [
self._keys
copy];
320 var keys =
self._keys,
325 values.push(
self.valueForKey(keys[index]));
338 - (CPArray)allKeysForObject:(
id)anObject
340 var keys =
self._keys,
347 for (; index < count; ++index)
350 value =
self._buckets[key];
352 if (value.isa && anObject && anObject.isa && [value respondsToSelector:
@selector(
isEqual:)] && [value
isEqual:anObject])
353 matchingKeys.push(key);
354 else if (value === anObject)
355 matchingKeys.push(key);
361 - (CPArray)keysOfEntriesPassingTest:(Function )predicate
366 - (CPArray)keysOfEntriesWithOptions:(CPEnumerationOptions)options passingTest:(Function )predicate
368 var keys =
self._keys;
370 if (options & CPEnumerationReverse)
372 var index = [keys count] - 1,
383 var matchingKeys = [],
387 stopRef = @ref(shouldStop);
389 for (; index !== stop; index += increment)
392 value =
self._buckets[key];
394 if (predicate(key, value, stopRef))
395 matchingKeys.push(key);
404 - (CPArray)keysSortedByValueUsingComparator:(Function )comparator
406 return [[
self allKeys] sortedArrayUsingFunction:function(a, b)
411 return comparator(a, b);
416 - (CPArray)keysSortedByValueUsingSelector:(
SEL)theSelector
418 return [[
self allKeys] sortedArrayUsingFunction:function(a, b)
423 return [a performSelector:theSelector withObject:b];
441 return [[_CPDictionaryValueEnumerator alloc] initWithDictionary:self];
449 if (
self === aDictionary)
452 var count = [
self count];
454 if (count !== [aDictionary count])
462 var currentKey = keys[index],
463 lhsObject =
self._buckets[currentKey],
464 rhsObject = aDictionary._buckets[currentKey];
466 if (lhsObject === rhsObject)
469 if (lhsObject && lhsObject.isa && rhsObject && rhsObject.isa && [lhsObject respondsToSelector:
@selector(
isEqual:)] && [lhsObject
isEqual:rhsObject])
480 if (
self === anObject)
517 - (id)objectForKey:(
id)aKey
519 var
object =
self._buckets[aKey];
521 return (
object === undefined) ? nil : object;
548 - (void)removeAllObjects
550 self.removeAllValues();
557 - (void)removeObjectForKey:(
id)aKey
559 self.removeValueForKey(aKey);
566 - (void)removeObjectsForKeys:(CPArray)keysForRemoval
568 var index = keysForRemoval.length;
591 - (void)setObject:(
id)anObject forKey:(
id)aKey
596 if (anObject === nil)
599 self.setValueForKey(aKey, anObject);
610 var keys = [aDictionary
allKeys],
611 index = [keys count];
615 var key = keys[index];
633 for (; index < count; ++index)
638 var key = keys[index],
639 value =
self.valueForKey(key);
647 - (BOOL)containsKey:(
id)aKey
650 return ((value !== nil) && (value !== undefined));
653 - (void)enumerateKeysAndObjectsUsingBlock:(Function )aFunction
656 shouldStopRef = @ref(shouldStop),
660 for (var index = 0; index < count; index++)
662 var key = keys[index],
663 value =
self.valueForKey(key);
665 aFunction(key, value, shouldStopRef);
672 - (void)enumerateKeysAndObjectsWithOptions:(CPEnumerationOptions)opts usingBlock:(Function )aFunction
691 return [aCoder _decodeDictionaryOfObjectsForKey:@"CP.objects"];
700 [aCoder _encodeDictionaryOfObjects:self forKey:@"CP.objects"];
707 @implementation _CPDictionaryValueEnumerator :
CPEnumerator
720 _dictionary = aDictionary;
728 var key = [_keyEnumerator nextObject];
733 return [_dictionary objectForKey:key];