Last active
July 7, 2023 15:53
-
-
Save Geokureli/ca54e1b0afc3a69d645eefb58fe57a90 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
typedef JsonMapRaw<T> = | |
{ | |
var keys:Array<String>; | |
var values:Array<T>; | |
} | |
/** | |
* A list of keys and values, used to serialize maps, usually for JSON or external saving. | |
* Note: Not meant to replace maps in any way, only meant for converting to and from json. | |
*/ | |
abstract JsonMap<T>(JsonMapRaw<T>) from JsonMapRaw<T> | |
{ | |
public function new (?keys:Array<String>, ?values:Array<T>) | |
{ | |
if (keys == null) | |
keys = []; | |
if (values == null) | |
values = []; | |
this = { keys:keys, values:values }; | |
} | |
@:arrayAccess | |
public function set(key:String, value:T):T | |
{ | |
var index = this.keys.indexOf(key); | |
if (index == -1) | |
index = this.keys.push(key) - 1; | |
return this.values[index] = value; | |
} | |
/** | |
* Retrieves the value with the specified key. If no key exists, `null` is returned. | |
*/ | |
@:arrayAccess | |
public function get(key:String):Null<T> | |
{ | |
final index = this.keys.indexOf(key); | |
return index == -1 ? null : this.values[index]; | |
} | |
/** | |
* Retrieves the value with the specified key without checking if the key exists. | |
*/ | |
public function getUnsafe(key:String):T | |
{ | |
return this.values[this.keys.indexOf(key)]; | |
} | |
/** | |
* Simply adds the key and value, does NOT check that the key is new. | |
* @param key | |
* @param value | |
*/ | |
public function addUnsafe(key:String, value:T) | |
{ | |
this.keys.push(key); | |
this.values.push(value); | |
} | |
public function exists(key:String):Bool | |
{ | |
return this.keys.contains(key); | |
} | |
public function iterator() | |
{ | |
return this.values.iterator(); | |
} | |
public function keys() | |
{ | |
return this.keys.iterator(); | |
} | |
public function keyValueIterator():KeyValueIterator<String, T> | |
{ | |
return new JsonMapKeyValueIterator(this); | |
// JsonMapKeyValueIterator<JsonMap.T> should be KeyValueIterator<String, JsonMap.T> | |
} | |
public function toString() | |
{ | |
var result = ""; | |
var first = true; | |
for (key=>value in keyValueIterator()) | |
{ | |
if (!first) | |
result += ', '; | |
first = false; | |
result += '"$key" => $value'; | |
} | |
} | |
public function toMap(?map:Map<String, T>) | |
{ | |
if (map == null) | |
map = []; | |
for (key=>value in keyValueIterator()) | |
map.set(key, value); | |
return map; | |
} | |
static public function fromMap<T>(map:Map<String, T>) | |
{ | |
final result = new JsonMap<T>(); | |
for (key=>value in map) | |
result.addUnsafe(key, value); | |
return result; | |
} | |
} | |
class JsonMapKeyValueIterator<T> | |
{ | |
final map:JsonMapRaw<T>; | |
var index:Int; | |
inline public function new(map:JsonMap<T>) | |
{ | |
this.map = cast map; | |
this.index = 0; | |
} | |
inline public function hasNext() | |
{ | |
return map.keys.length > index; | |
} | |
inline public function next() | |
{ | |
final i = index++; | |
return { key:map.keys[i], value:map.values[i] }; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment