Last active
February 4, 2025 11:36
-
-
Save tabularelf/547b62efbcb0beaa8e6478afae8e693f to your computer and use it in GitHub Desktop.
Convert ds_grid/map/list to struct/array equivalents and vice versa
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
/* | |
Created by: TabularElf. https://tabularelf.com/ | |
Clarification: This is a set of scripts that allow you to convert ds_maps, ds_lists and ds_grids into structs/arrays and vice versa. | |
Addtionally, ds_maps and ds_lists will automatically convert ds_map/ds_list children into structs/arrays, and vice versa. | |
You can disable this by assigning the optional argument [convert_children] to false when calling the function. | |
Note: This does not convert any data structures that are stored within or as ds_grids and vice versa. | |
Also to access a cell from an array2D of a ds_grid, you will do the following. | |
grid[cell_x][cell_y] | |
*/ | |
function __ds_struct_array_conversion_throw(_string) { | |
var _callStack = debug_get_callstack(); | |
array_delete(_callStack, 0, 1); | |
throw { | |
message: _string, | |
longMessage: _string, | |
stacktrace: _callStack | |
} | |
} | |
/// @func ds_map_from_struct(struct) | |
/// @param struct | |
/// @param [convert_children] | |
function ds_map_from_struct(_struct, _nested = true) { | |
// Error Checking | |
if !is_struct(_struct) { | |
__ds_struct_array_conversion_throw("Not a struct"); | |
} | |
var _structKeys = variable_struct_get_names(_struct); | |
var _map = ds_map_create(); | |
var _len = array_length(_structKeys); | |
var _i = 0; | |
repeat(_len) { | |
var _key = _structKeys[_i]; | |
if (_nested) { | |
if is_struct(_struct[$ _key]) { | |
// Struct | |
ds_map_add_map(_map, _key, ds_map_from_struct(_struct[$ _key])); | |
++_i; | |
continue; | |
} else if is_array(_struct[$ _key]) { | |
// Array | |
ds_map_add_list(_map, _key, ds_list_from_array(_struct[$ _key])); | |
++_i; | |
continue; | |
} | |
} | |
_map[? _structKeys[_i]] = _struct[$ _structKeys[_i]]; | |
++_i; | |
} | |
return _map; | |
} | |
/// @func ds_map_to_struct(ds_map) | |
/// @param ds_map | |
/// @param [convert_children] | |
function ds_map_to_struct(_map, _nested = true) { | |
// Error Checking | |
if !ds_exists(_map, ds_type_map) { | |
__ds_struct_array_conversion_throw("Not a ds_map"); | |
} | |
var _mapKeys = ds_map_keys_to_array(_map); | |
var _struct = {}; | |
var _len = array_length(_mapKeys); | |
var _i = 0; | |
repeat(_len) { | |
var _key = _mapKeys[_i]; | |
if (_nested) { | |
if ds_map_is_map(_map, _key) { | |
// For DS_MAPs | |
_struct[$ _key] = ds_map_to_struct(_map[? _key]); | |
++_i; | |
continue; | |
} else if ds_map_is_list(_map, _key) { | |
// The DS_LIST | |
_struct[$ _key] = ds_list_to_array(_map[? _key]); | |
++_i; | |
continue; | |
} | |
} | |
// For everything else | |
_struct[$ _key] = _map[? _key]; | |
++_i; | |
} | |
return _struct; | |
} | |
/// @func ds_list_from_array(array) | |
/// @param array | |
/// @param [convert_children] | |
function ds_list_from_array(_array, _nested = true) { | |
// Error Checking | |
if !is_array(_array) { | |
__ds_struct_array_conversion_throw("Not an array"); | |
} | |
var _len = array_length(_array); | |
var _list = ds_list_create(); | |
ds_list_set(_list,_len-1,0); | |
var _i = 0; | |
repeat(_len) { | |
var _index = _array[_i]; | |
if (_nested) { | |
if is_struct(_index) { | |
// Struct | |
_list[| _i] = _index; | |
ds_list_mark_as_map(_list, _i); | |
++_i; | |
continue; | |
} else if is_array(_index) { | |
// Array | |
_list[| _i] = _index; | |
ds_list_mark_as_list(_list, _i); | |
++_i; | |
continue; | |
} | |
} | |
_list[| _i] = _index; | |
++_i; | |
} | |
return _list; | |
} | |
/// @func ds_list_to_array(ds_list) | |
/// @param ds_list | |
/// @param [convert_children] | |
function ds_list_to_array(_list, _nested = true) { | |
// Error Checking | |
if !ds_exists(_list, ds_type_list) { | |
__ds_struct_array_conversion_throw("Not a ds_list"); | |
} | |
var _listSize = ds_list_size(_list); | |
var _array = array_create(_listSize-1,0); | |
var _len = _listSize; | |
var _i = 0; | |
repeat(_len) { | |
var _index = _list[| _i]; | |
if (_nested) { | |
if ds_list_is_map(_list, _i) { | |
_array[_i] = ds_map_to_struct(_index); | |
++_i; | |
continue; | |
} else if ds_list_is_list(_list, _i) { | |
_array[_i] = ds_list_to_array(_index); | |
++_i; | |
continue; | |
} | |
} | |
_array[_i] = _index; | |
++_i; | |
} | |
return _array; | |
} | |
/// @func ds_grid_from_array2D(array2D) | |
/// @param array2D | |
function ds_grid_from_array2D(_array) { | |
// Error Checking | |
if !is_array(_array) { | |
__ds_struct_array_conversion_throw("Not an array"); | |
} | |
var _width = array_length(_array); | |
var _grid = ds_grid_create(_width,1); | |
var _gridHeight = 1; | |
var _i = 0; | |
repeat(_width) { | |
if (is_array(_array[_i])) { | |
var _height = array_length(_array[_i]); | |
if _height > _gridHeight { | |
ds_grid_resize(_grid,ds_grid_width(_grid)-1,_height); | |
_gridHeight = _height; | |
} | |
var _j = 0; | |
repeat(_height) { | |
_grid[# _i, _j] = _array[_i][_j]; | |
++_j; | |
} | |
} | |
++_i; | |
} | |
return _grid; | |
} | |
/// @func ds_grid_to_array2D(ds_grid) | |
/// @param ds_grid | |
function ds_grid_to_array2D(_grid) { | |
// Error Checking | |
if !ds_exists(_grid, ds_type_grid) { | |
__ds_struct_array_conversion_throw("Not a ds_grid"); | |
} | |
var _gridWidth = ds_grid_width(_grid); | |
var _gridHeight = ds_grid_height(_grid); | |
var _array = array_create(_gridWidth,0); | |
var _i = 0; | |
repeat(_gridWidth) { | |
_array[_i] = array_create(_gridHeight, 0); | |
var _j = 0; | |
repeat(_gridHeight) { | |
_array[_i][_j] = _grid[# _i, _j]; | |
++_j; | |
} | |
++_i; | |
} | |
return _array; | |
} |
You got some valid and genuine use cases where you need to do a partial conversion???
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
suggest changing the convert children arguments over to
depth
which defaults to infinity