mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-08-25 04:57:03 +00:00
NEW: for..of iterator for CPDictionary (#3113)
This commit is contained in:
@@ -774,4 +774,4 @@ if (CFMutableDictionary.prototype.isa !== CPMutableDictionary)
|
||||
writable: true
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,6 +133,25 @@ CFDictionary.prototype.valueForKey = function(/*String*/ aKey)
|
||||
|
||||
DISPLAY_NAME(CFDictionary.prototype.valueForKey);
|
||||
|
||||
// This allows the use of 'for...of' loops directly on CFDictionary instances.
|
||||
CFDictionary.prototype[Symbol.iterator] = function*()
|
||||
{
|
||||
// Access the internal storage directly for maximum performance.
|
||||
// 'this._keys' is the internal array of keys.
|
||||
const keys = this._keys;
|
||||
|
||||
// 'this._buckets' is the internal hash map of key -> value.
|
||||
const buckets = this._buckets;
|
||||
|
||||
// A 'for...of' loop on an array is itself a lazy and efficient way to iterate.
|
||||
for (const key of keys)
|
||||
{
|
||||
// 'yield' pauses the generator and returns the [key, value] pair
|
||||
// to the consumer (the for...of loop).
|
||||
yield [key, buckets[key]];
|
||||
}
|
||||
};
|
||||
|
||||
CFDictionary.prototype.toString = function()
|
||||
{
|
||||
var string = "{\n",
|
||||
|
||||
@@ -484,4 +484,43 @@
|
||||
[self assert:5 equals:[dict objectForKey:@"aKey"]];
|
||||
}
|
||||
|
||||
- (void)testForOfIteration
|
||||
{
|
||||
var dict = @{ @"a": 1, @"b": 2, @"c": 3 };
|
||||
var result = [CPMutableDictionary dictionary];
|
||||
|
||||
// Test basic for...of iteration
|
||||
for (var [key, value] of dict)
|
||||
{
|
||||
[result setObject:value forKey:key];
|
||||
}
|
||||
|
||||
[self assert:dict equals:result message:@"Dictionary should be equal after for...of iteration"];
|
||||
|
||||
// Test with spread syntax, a common use for iterables
|
||||
var entries = [...dict];
|
||||
[self assert:3 equals:entries.length message:@"Spread syntax should produce 3 entries"];
|
||||
|
||||
// The order is not guaranteed, so we check the contents by converting to a dictionary
|
||||
var spreadDict = [CPMutableDictionary dictionary];
|
||||
for (var entry of entries)
|
||||
{
|
||||
[spreadDict setObject:entry[1] forKey:entry[0]];
|
||||
}
|
||||
[self assert:dict equals:spreadDict message:@"Dictionary rebuilt from spread entries should be equal"];
|
||||
|
||||
// Test on an empty dictionary
|
||||
var emptyDict = @{};
|
||||
var iterations = 0;
|
||||
for (var entry of emptyDict)
|
||||
{
|
||||
iterations++;
|
||||
}
|
||||
[self assert:0 equals:iterations message:@"for...of on an empty dictionary should not iterate"];
|
||||
|
||||
// Test with spread on empty dictionary
|
||||
var emptyEntries = [...emptyDict];
|
||||
[self assert:0 equals:emptyEntries.length message:@"Spread on an empty dictionary should produce an empty array"];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user