mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-09-06 02:43:40 +00:00
Merge pull request #1617 from slevenbits/dictionary-key-methods
CPDictionary key methods keysOfEntriesPassingTest: keysOfEntriesWithOptions:passingTest: keysSortedByValueUsingComparator:
This commit is contained in:
+70
-13
@@ -25,6 +25,7 @@
|
||||
@import "CPException.j"
|
||||
@import "CPNull.j"
|
||||
@import "CPObject.j"
|
||||
#import "Ref.h"
|
||||
|
||||
/* @ignore */
|
||||
@implementation _CPDictionaryValueEnumerator : CPEnumerator
|
||||
@@ -359,30 +360,86 @@
|
||||
var count = _keys.length,
|
||||
index = 0,
|
||||
matchingKeys = [],
|
||||
thisKey = nil,
|
||||
thisValue = nil;
|
||||
key = nil,
|
||||
value = nil;
|
||||
|
||||
for (; index < count; ++index)
|
||||
{
|
||||
thisKey = _keys[index];
|
||||
thisValue = _buckets[thisKey];
|
||||
if (thisValue.isa && anObject && anObject.isa && [thisValue respondsToSelector:@selector(isEqual:)] && [thisValue isEqual:anObject])
|
||||
matchingKeys.push(thisKey);
|
||||
else if (thisValue === anObject)
|
||||
matchingKeys.push(thisKey);
|
||||
key = _keys[index];
|
||||
value = _buckets[key];
|
||||
|
||||
if (value.isa && anObject && anObject.isa && [value respondsToSelector:@selector(isEqual:)] && [value isEqual:anObject])
|
||||
matchingKeys.push(key);
|
||||
else if (value === anObject)
|
||||
matchingKeys.push(key);
|
||||
}
|
||||
|
||||
return matchingKeys;
|
||||
}
|
||||
|
||||
- (CPArray)keysOfEntriesPassingTest:(Function /*(id key, id obj, @ref BOOL stop)*/)predicate
|
||||
{
|
||||
return [self keysOfEntriesWithOptions:CPEnumerationNormal passingTest:predicate];
|
||||
}
|
||||
|
||||
- (CPArray)keysOfEntriesWithOptions:(CPEnumerationOptions)options passingTest:(Function /*(id key, id obj, @ref BOOL stop)*/)predicate
|
||||
{
|
||||
if (options & CPEnumerationReverse)
|
||||
{
|
||||
var index = [_keys count] - 1,
|
||||
stop = -1,
|
||||
increment = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
var index = 0,
|
||||
stop = [_keys count],
|
||||
increment = 1;
|
||||
}
|
||||
|
||||
var matchingKeys = [],
|
||||
key = nil,
|
||||
value = nil,
|
||||
shouldStop = NO,
|
||||
stopRef = AT_REF(shouldStop);
|
||||
|
||||
for (; index !== stop; index += increment)
|
||||
{
|
||||
key = _keys[index];
|
||||
value = _buckets[key];
|
||||
|
||||
if (predicate(key, value, stopRef))
|
||||
matchingKeys.push(key);
|
||||
|
||||
if (shouldStop)
|
||||
break;
|
||||
}
|
||||
|
||||
return matchingKeys;
|
||||
}
|
||||
|
||||
- (CPArray)keysSortedByValueUsingComparator:(Function /*(id obj1, id obj2)*/)comparator
|
||||
{
|
||||
return [[self allKeys] sortedArrayUsingFunction:function(a, b)
|
||||
{
|
||||
a = [self objectForKey:a];
|
||||
b = [self objectForKey:b];
|
||||
|
||||
return comparator(a, b);
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
- (CPArray)keysSortedByValueUsingSelector:(SEL)theSelector
|
||||
{
|
||||
return [[self allKeys] sortedArrayUsingFunction:function(a, b) {
|
||||
a = [self objectForKey:a];
|
||||
b = [self objectForKey:b];
|
||||
return [[self allKeys] sortedArrayUsingFunction:function(a, b)
|
||||
{
|
||||
a = [self objectForKey:a];
|
||||
b = [self objectForKey:b];
|
||||
|
||||
return [a performSelector:theSelector withObject:b];
|
||||
}];
|
||||
return [a performSelector:theSelector withObject:b];
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -206,6 +206,77 @@
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)testKeysOfEntriesPassingTest
|
||||
{
|
||||
var numberDictionary = [CPDictionary dictionaryWithJSObject:{
|
||||
key1: 5,
|
||||
key2: 1,
|
||||
key3: 4,
|
||||
key4: 2,
|
||||
key5: 3
|
||||
}];
|
||||
|
||||
var expected = [@"key1", @"key3"],
|
||||
result = [numberDictionary keysOfEntriesPassingTest:function(key, value, stop)
|
||||
{
|
||||
return value >= 4;
|
||||
}];
|
||||
|
||||
[self assert:expected equals:result];
|
||||
|
||||
expected = [@"key3", @"key1"],
|
||||
result = [numberDictionary keysOfEntriesWithOptions:CPEnumerationReverse passingTest:function(key, value, stop)
|
||||
{
|
||||
return value >= 4;
|
||||
}];
|
||||
|
||||
[self assert:expected equals:result];
|
||||
|
||||
expected = [@"key3"],
|
||||
result = [numberDictionary keysOfEntriesWithOptions:CPEnumerationReverse passingTest:function(key, value, stop)
|
||||
{
|
||||
if (value === 4)
|
||||
stop(YES);
|
||||
|
||||
return value >= 4;
|
||||
}];
|
||||
|
||||
[self assert:expected equals:result];
|
||||
|
||||
var stringDictionary = [CPDictionary dictionaryWithJSObject:{
|
||||
a: @"Z", b: @"y", c: @"X", d: @"W",
|
||||
e: @"V", f: @"u", g: @"T", h: @"s",
|
||||
i: @"R", j: @"q", k: @"P", l: @"o"
|
||||
}];
|
||||
|
||||
expected = [@"j", @"k", @"l"];
|
||||
result = [stringDictionary keysOfEntriesPassingTest:function(key, value, stop)
|
||||
{
|
||||
return value.toLowerCase() <= @"q";
|
||||
}];
|
||||
|
||||
[self assert:expected equals:result];
|
||||
|
||||
expected = [@"l", @"k", @"j"];
|
||||
result = [stringDictionary keysOfEntriesWithOptions:CPEnumerationReverse passingTest:function(key, value, stop)
|
||||
{
|
||||
return value.toLowerCase() <= @"q";
|
||||
}];
|
||||
|
||||
[self assert:expected equals:result];
|
||||
|
||||
expected = [@"j", @"k"];
|
||||
result = [stringDictionary keysOfEntriesPassingTest:function(key, value, stop)
|
||||
{
|
||||
if (value === @"P")
|
||||
stop(YES);
|
||||
|
||||
return value.toLowerCase() <= "q";
|
||||
}];
|
||||
|
||||
[self assert:expected equals:result];
|
||||
}
|
||||
|
||||
- (void)testKeysSortedByValueUsingSelector
|
||||
{
|
||||
var numberDictionary = [CPDictionary dictionaryWithJSObject:{
|
||||
@@ -237,6 +308,46 @@
|
||||
[self assert:expected equals:result];
|
||||
}
|
||||
|
||||
- (void)testKeysSortedByValueUsingComparator
|
||||
{
|
||||
var numberDictionary = [CPDictionary dictionaryWithJSObject:{
|
||||
key1: 5,
|
||||
key2: 1,
|
||||
key3: 4,
|
||||
key4: 2,
|
||||
key5: 3
|
||||
}];
|
||||
|
||||
var expected = [@"key2", @"key4", @"key5", @"key3", @"key1"],
|
||||
result = [numberDictionary keysSortedByValueUsingComparator:function(obj1, obj2)
|
||||
{
|
||||
return obj1 < obj2 ? CPOrderedAscending : CPOrderedDescending;
|
||||
}];
|
||||
|
||||
[self assert:expected equals:result];
|
||||
|
||||
var stringDictionary = [CPDictionary dictionaryWithJSObject:{
|
||||
a: @"Z", b: @"y", c: @"X", d: @"W",
|
||||
e: @"V", f: @"u", g: @"T", h: @"s",
|
||||
i: @"R", j: @"q", k: @"P", l: @"o"
|
||||
}];
|
||||
|
||||
expected = [@"l", @"k", @"j", @"i", @"h", @"g", @"f", @"e", @"d", @"c", @"b", @"a"];
|
||||
result = [stringDictionary keysSortedByValueUsingComparator:function(obj1, obj2)
|
||||
{
|
||||
return obj1.toLowerCase() < obj2.toLowerCase() ? CPOrderedAscending : CPOrderedDescending;
|
||||
}];
|
||||
|
||||
[self assert:expected equals:result];
|
||||
|
||||
expected = [@"k", @"i", @"g", @"e", @"d", @"c", @"a", @"l", @"j", @"h", @"f", @"b"];
|
||||
result = [stringDictionary keysSortedByValueUsingComparator:function(obj1, obj2)
|
||||
{
|
||||
return obj1 < obj2 ? CPOrderedAscending : CPOrderedDescending;
|
||||
}];
|
||||
[self assert:expected equals:result];
|
||||
}
|
||||
|
||||
- (void)testJSObjectDescription
|
||||
{
|
||||
var dict = [[CPDictionary alloc] initWithObjects:[CGRectMake(1, 2, 3, 4), CGPointMake(5, 6)] forKeys:[@"key1", @"key2"]],
|
||||
|
||||
Reference in New Issue
Block a user