diff --git a/sources/Data/Collections/AssociativeArray.uc b/sources/Data/Collections/AssociativeArray.uc index dffba1b..7af613f 100644 --- a/sources/Data/Collections/AssociativeArray.uc +++ b/sources/Data/Collections/AssociativeArray.uc @@ -464,7 +464,12 @@ public function Empty(optional bool deallocateKeys) * * Collecting all keys from the `AssociativeArray` is O(). * + * See also `CopyTextKeys()` methods. + * * @return Array of all the caller `AssociativeArray`'s keys. + * This method does not return copies of keys, but actual keys instead - + * deallocating them will remove their item from + * the caller `AssociativeArray`. */ public final function array GetKeys() { @@ -482,6 +487,43 @@ public final function array GetKeys() return result; } +/** + * Returns copies of `Text` key of all properties inside caller + * `AssociativeArray`. Keys that have a different class (even if they are + * a child class for `Text`) are not returned. + * + * This method exists to provide alternative to `GetKeys()` method that would + * return copies of keys instead of actually used references: we cannot make + * a copy of an arbitrary `AcediaObject`, but we can of `Text`. + * Which is also a most common type for the keys. + * + * Collecting all keys from the `AssociativeArray` is O(). + * + * @return Array of all the caller `AssociativeArray`'s keys that have exactly + * `Text` class. + */ +public final function array CopyTextKeys() +{ + local int i, j; + local Text nextKeyAsText; + local array result; + local array nextEntry; + for (i = 0; i < hashTable.length; i += 1) + { + CleanBucket(hashTable[i]); + nextEntry = hashTable[i].entries; + for (j = 0; j < nextEntry.length; j += 1) + { + nextKeyAsText = Text(nextEntry[j].key); + if (nextKeyAsText != none && nextKeyAsText.class == class'Text') + { + result[result.length] = nextKeyAsText.Copy(); + } + } + } + return result; +} + /** * Returns amount of elements in the caller `AssociativeArray`. * diff --git a/sources/Data/Collections/Tests/TEST_AssociativeArray.uc b/sources/Data/Collections/Tests/TEST_AssociativeArray.uc index ccbf77a..2a397dd 100644 --- a/sources/Data/Collections/Tests/TEST_AssociativeArray.uc +++ b/sources/Data/Collections/Tests/TEST_AssociativeArray.uc @@ -25,6 +25,7 @@ protected static function TESTS() Test_GetSet(); Test_HasKey(); Test_GetKeys(); + Test_CopyTextKeys(); Test_Remove(); Test_CreateItem(); Test_Empty(); @@ -127,6 +128,37 @@ protected static function Test_GetKeys() } } +protected static function Test_CopyTextKeys() +{ + local array allKeys; + local array keys; + local AssociativeArray array; + array = AssociativeArray(__().memory.Allocate(class'AssociativeArray')); + Context("Testing `CopyTextKeys()` method for `AssociativeArray`."); + array.SetItem(__().text.FromString("key"), __().text.FromString("value")); + array.SetItem(__().box.int(13), __().text.FromString("value #2")); + array.SetItem(__().box.float(-925.274), __().text.FromString("value #2")); + array.SetItem(__().text.FromString("second key"), __().box.bool(true)); + + Issue("`CopyTextKeys()` does not return correct set of keys."); + keys = array.CopyTextKeys(); + TEST_ExpectTrue(keys.length == 2); + TEST_ExpectTrue( + (keys[0].ToPlainString() == "key" + && keys[1].ToPlainString() == "second key") + || (keys[0].ToPlainString() == "second key" + && keys[1].ToPlainString() == "key")); + + Issue("Deallocating keys returned by `CopyTextKeys()` affects their" + @ "source collection."); + allKeys = array.GetKeys(); + TEST_ExpectTrue(allKeys.length == 4); + TEST_ExpectNotNone(array.GetItem(__().text.FromString("key"))); + TEST_ExpectNotNone(array.GetItem(__().text.FromString("second key"))); + TEST_ExpectTrue( + array.GetText(__().text.FromString("key")).ToPlainString() == "value"); +} + protected static function Test_Remove() { local AcediaObject key1, key2, key3;