• Models
  • Contests
  • Slicer
  • Login
  • Start Here
    thingiverse-iconprintables-iconcults3d-iconmakerworld-iconmyminifactory-icon

    3D GO

    3D ModelsContestsCollectionsSaved ModelsOn a mobile device?

3D GO

Privacy Policy
OpenSCAD Library for Hash data structure 3D Printer File Image 1
OpenSCAD Library for Hash data structure 3D Printer File Thumbnail 1

OpenSCAD Library for Hash data structure

af12689 avataraf12689

July 8, 2022

printables-icon
DescriptionCommentsTags

Description

For some complex OpenSCAD projects I wanted to have to ability to put many different settings for a module into one parameter as a hash / associative array. This would be useful when I have a large number of settings and module which call sub-modules which call sub-sub-modules.

Putting these settings into module parameters would be unwieldy, especially if I have to add a settings later. Putting these settings into global parameters prevents me from using the module with several different settings at the same time.

OpenSCAD does not natively support hashes / associative array (as of mid 2022). But it does have a search() function that can (among other things) locate a string in an array.

So I build this library that encapsulates the creation, modification and use of hashes.
This library can be used by including the following line:

use <af-hash.scad>

 

The basic use case is where I have a module that can receive any number of settings in one parameter, and I can call this module with different settings. Optionally the module calls a sub-module which also uses these settings.

Example:

use <af-hash.scad>

settings1 = hash_create([
	"size", [10,20,30],
	"wall-thickness", 2,
	"hole-diameter", 5
]);
settings2 = hash_create([
	"size", [20,30,60],
	"wall-thickness", 3,
	"hole-diameter", 8
]);


translate([-30,0,0]) my_module(settings1);
translate([30,0,0]) my_module(settings2);


module my_module(settings) {
	s = hash_get(settings, "size");
	w = hash_get(settings, "wall-thickness");
[...]
	my_submodule(settings);
[...]
}

module my_submodule(settings) {
	w = hash_get(settings, "wall-thickness");
	d = hash_get(settings, "hole-diameter");
[...]
}

 

The functions in this library are (the most important function are in bold):

  • hash_create(array) - takes an array in the form [ key1, value1, key2, value2, … ] and converts it into a proper hash
  • hash_get(hash, key, [default_value = undef]) - searches in the hash for the given key and returns the associated value, returns the default value if the key was not found or if the assosiated value is undef
  • hash_get2(hash, key) - searches in the hash for the given key and returns the associated value and a flag that says if the key was found
  • hash_contains_key(hash, key) - tests if the hash contains the key
  • hash_set - returns a modified hash
    • hash_set(hash, key, value) - returns a hash where the key-value pair is added or, if the key already existed, the value is overridden
    • hash_set(hash, array) - same as above, but takes multiple key-value pair in the same format as hash_create
    • hash_set(hash1, hash2) - returns a hash were the entries of both input hashes are merged, values of hash2 override values with the same key from hash1
  • hash_empty() - creates an empty hash
  • hash_keys(hash) - returns a list of all keys in the hash
  • module hash_print(hash, [long_format = false]) - prints the hash to the console

Update 2022-07-30:

Added the following function:

  • hash_prune(hash) - creates a new hash with only the currently valid entries from parameter hash, overridden values are omitted

Some technical details:

Hashes are internally stored as a vector of vectors of key and value:

hash = [
	[ <key1>, <value1> ],
	[ <key2>, <value2> ],
	[ <key3>, <value3> ],
	etc.
];

Hash keys are automatically converted to strings both during creation of the hash and during access of the hash data.

Hash values can be any kind of data, including undef, number, vector, string or a hash.

As hash_print will show you, hash_set does not actually modify the old hash. Instead it puts the new values at the start of the newly generated hash: 

hash1 = [
	[ "abc", 1 ],
	[ "def", 2 ]
];
hash2 = [
	[ "def", 3 ],
	[ "ghi", 4 ]
];
hash3 = hash_set(hash1, hash2);
==> hash3 = [
	[ "def", 3 ],
	[ "ghi", 4 ],
	[ "abc", 1 ],
	[ "def", 2 ]
];

hash_get("def") will find the new value (3) first and return it instead of the old value (2).

A hash value can be “deleted” by overriding it with the value undef. The key still counts as contained in the hash, but hash_get will return the default value (which is also undef if not specified).

hash_create allows key-value pairs in sub-arrays, sub-sub-arrays etc., it will flatten the data into the above described hash structure:

hash = hash_create([ "ab",1, "cd",2, [ "ef",3, [ "gh",4 ] ], "ij",5 ]);
==> hash = [
	[ "ab", 1 ],
	[ "cd", 2 ],
	[ "ef", 3 ],
	[ "gh", 4 ],
	[ "ij", 5 ]
];

The value overriding mechanism can create quite big hashes. The output of hash_print will then be difficult to read. By using hash_prune the hash will be smaller because all overridden values are removed:

hash1 = hash_create([ "a",1, "b",2, "a",3, "c",4, "a",5 ]);
==> hash1 = [
	[ "a", 1 ],
	[ "b", 2 ],
	[ "a", 3 ],
	[ "c", 4 ],
	[ "a", 5 ]
];
hash2 = hash_prune(hash1);
==> hash2 = [
	[ "a", 1 ],
	[ "b", 2 ],
	[ "c", 4 ]
];

License:

Creative Commons — Attribution

Related Models

Thor Mjolnir Hammer Bic Pen preview image

Thor Mjolnir Hammer Bic Pen

effektz profile image

effektz

9,090

Diverse Schilder / various labels  for hobby & makers preview image

Diverse Schilder / various labels for hobby & makers

RPK profile image

RPK

2

Cute Fluffy Puppy Figurine to Print preview image

Cute Fluffy Puppy Figurine to Print

bonowski. profile image

bonowski.

3

Vorpal The Hexapod Walking Robot preview image

Vorpal The Hexapod Walking Robot

vorpal profile image

vorpal

4,986

MakerZ – Open Source 1/28 RC Drift Chassis by Fails & Makes | Açık Kaynak 1/28 RC Drift Şasisi preview image

MakerZ – Open Source 1/28 RC Drift Chassis by Fails & Makes | Açık Kaynak 1/28 RC Drift Şasisi

Fails&Makes profile image

Fails&Makes

Customizable EU License Plate Keychain preview image

Customizable EU License Plate Keychain

John_M profile image

John_M

42

Snap-Together Mini Minecraft Jack-O-Lantern with integrated LED preview image

Snap-Together Mini Minecraft Jack-O-Lantern with integrated LED

scottrlindsey profile image

scottrlindsey

4,453

Small Parts Storage Drawers - Organizer preview image

Small Parts Storage Drawers - Organizer

GT 3D Makers profile image

GT 3D Makers

29

9