Hash table
In computing, a hash table, also known as hash map, is a data structure that implements an associative array or dictionary. It is an abstract data type that maps keys to values.
A hash table uses a hash function to compute an index, also called a hash code, into an array of buckets or slots, from which the desired value can be found. During lookup, the key is hashed and the resulting hash indicates where the corresponding value is stored.
The average time complexity for search, insert and delete in Big-O notation for a hash map is O(1)
Let's declare a hash map of string keys to double values:
var gases map[string]float64
/*
Map types are reference types, like pointers or slices,
and so the value of m above is nil; it doesn’t point to
an initialized map. A nil map behaves like an empty map
when reading, but attempts to write to a nil map will
cause a runtime panic; don’t do that. To initialize
a map, use the built in make function
*/
gases := make(map[string]float64)
/*
The make function allocates and initializes a hash
map data structure and returns a map value that
points to it.
*/
let gases: Record<string, number> = {}
var gases = <String, double>{}
gases: dict[str, float] = {} # Python 3.9+
# Earlier versions of Python
from typing import Dict
gases: Dict{str, float} = {}
gases = Dict{String, Float64}()
There's a familiar syntax for adding a key value pair to maps:
Note: Dart must have a trailing semicolon
This statement retrieves the value stored under the key "nitrogen"
gas := gases["nitrogen"]
/*
If a key doesn't exist, it returns 0 for int value
But sometimes it might be that you set
the value of the key to 0, So in this case
we modify the get syntax like this
*/
gas, ok := gases["nitrogen"]
if ok {
fmt.Println("Gas:", gas)
} else {
fmt.Println("Gas not found")
}
// if key exists, ok will be true, otherwise false
let gas = gases.nitrogen ?? "Gas not found"
console.log(gas)
// for checking if key exists
let if_nitrogen = gases.hasOwnProperty("nitrogen")
var gas = gases["nitrogen"] ?? "Gas not found";
// for checking if key exists
var if_nitrogen = gases.containsKey("nitrogen");
gas = gases["nitrogen"]
# return default if key does not exist
gas = gases.get("nitrogen", "Gas not found")
gas = gases["nitrogen"]
#=
if key found, return value, else return given
default value if no mapping for the key
=#
gas = get(gases, "nitrogen", "Gas not found")
# OR
gas = get(gases, "nitrogen", 0.0)
#=
Return the value stored for the given key, or
if no mapping for the key is present, store
key => default, and return default
=#
gas = get!(gases, "nitrogn", 0.0)
Let's see the syntax for getting the length of hash map
length_gases = len(gases)
length_gases = Object.keys(gases).length
length_gases = gases.length
length_gases = len(gases)
length_gases = length(gases)
Let's see the syntax for deleting an entry from the map
delete(gases, "nitrogen")
gases.remove("nitrogen");
del gases["nitrogen"]
# pop gets value of key from map
# it exists, None otherwise,
# and then deletes key from map
gases.pop("nitrogen", None)
delete!(gases, "nitrogen")
# remove an item from dictionary and return it
pop!(gases, "nitrogen") # 78
pop!(gases, "O2") # error not found
# default if not found
pop!(gases, "02", 21)
To get only the keys of a map:
gases_names := []string{}
for key := range gases {
gases_names = append(gases_names, key)
}
fmt.Println(gases_names)
let gases_names: string[] = Object.keys(gases)
console.log(gases_names)
var gases_names = gases.keys;
print(gases_names.toList());
gases_names = list(gases.keys())
print(gases_names)
gases_names = collect(keys(gases))
println(gases_names)
To get only the values of a map:
gases_proportions := []float64{}
for _, value := range gases {
gases_proportions = append(gases_proportions, value)
}
fmt.Println(gases_proportions)
let gases_proportions: number[] = Object.values(gases)
console.log(gases_proportions)
var gases_proportions = gases.values;
print(gases_proportions.toList());
gases_proportions = list(gases.values())
print(gases_proportions)
gases_proportions = collect(values(gases))
println(gases_proportions)
To iterate over the contents of a map:
for k, v := range gases {
fmt.Printf("Key: %s Value: %.2f\n", k, v)
}
for (const [k, v] of Object.entries(gases)) {
console.log(`${k} : ${v}`);
}
gases.forEach((k,v) =>
print('$k: $v')
);
for k, v in gases.items():
print(f"{k}: {v}")
for (k, v) in gases
println("$k : $v")
end
Let's finalise with an advanced map initialization. Let's create an array of maps of key string containing a value which is a map of key string and value float
package main
import "fmt"
func main() {
gases := []map[string]map[string]float64{
{
"major": {
"nitrogen": 78,
"oxygen": 21,
},
"minor": {
"carbon_dioxide": 0.03,
"inert": 0.97,
},
},
{
"alien": {
"xenova": 0.00034,
},
},
}
fmt.Println(gases[0]["major"]["oxygen"])
}
let gases: Record<string, Record<string, number>>[] = [
{
"major": {
"nitogen": 78,
"oxygen": 21
},
"minor": {
"carbon_dioxide": 0.03,
"inert": 0.97
}
},
{
"alien": {
"xenova": 0.00034
}
}
]
console.log(gases[0]['major']['oxygen'])
void main() {
// Note that using var gases is still okay
// cause Dart will infer the type from the structure
List<Map<String, Map<String, double>>> gases = [
{
"major": {
"nitrogen": 78,
"oxygen": 21
},
"minor": {
"carbon_dioxide": 0.03,
"inert": 0.97
}
},
{
"alien": {
"xenova": 0.00034
}
}
];
// The ! is used to tell Dart that the receiver will not be null
// cause for sure there exists a value in that key
// Use ? to tell the compiler the posibility of it being null
// Will still work
print((gases[0]["major"])!["oxygen"]);
}
// Use mypy for type checking
gases: list[dict[str, dict[str, float]]] = [
{
"major": {
"nitrogen": 78,
"oxygen": 21
},
"minor": {
"carbon_dioxide": 0.03,
"inert": 0.97
}
},
{
"alien": {
"xenova": 0.00034
}
}
]
print(gases[0]["major"]["oxygen"])
#= OR JUST
gases::Vector{Dict{String, Dict}} = [
=#
gases::Vector{Dict{String, Dict{String, Float64}}} = [
Dict(
# You can or not set types of Dict
"major" => Dict{String, Float64}(
"nitrogen" => 78,
"oxygen" => 21
),
"minor" => Dict(
"inert" => 0.97,
"carbon_dioxide" => 0.03
)
),
Dict(
"alien" => Dict(
"xenova" => 0.00034
)
)
]
# Julia is 1-indexed based
println(gases[1]["major"]["oxygen"])