Skip to content

Multimap

Person8880 edited this page Sep 2, 2023 · 5 revisions

The multimap object is similar to the map object, with one key difference:

  • A map allows a single value per key, and adding a new value will replace the old one.
  • A multimap allows multiple distinct values per key. When you get a key, you get back an array structure containing all of the values that have been mapped to the key.

This abstracts away the fairly common need for having lists of values against a key in a table.

To get a new multimap, use:

local Multimap = Shine.Multimap()

You can construct a multimap from an existing multimap, or a table of tables:

-- Construct from a table.
local MultimapFromTable = Shine.Multimap{
    Cake = {
        "Delicious", "I would like more."
    }
}
-- Construct from another multimap as a (shallow) copy of it.
local MultimapFromMultimap = Shine.Multimap( MultimapFromTable )

As with maps, an unordered variant exists which does not preserve key-value insertion order but has constant-time element removal:

local Multimap = Shine.UnorderedMultimap()

Methods

A lot of methods are shared with the Map object, with a few small differences in behaviour.

Multimap:Add()

Adds a new key-value pair, providing the given key does not already have the given value stored against it.

-- Both calls add a new key-value pair, unlike a map.
Multimap:Add( "Cake", "Delicious" )
Multimap:Add( "Cake", "I would like more." )

The secondary value associated with the key-value pair is the value itself, and thus is effectively unused.

Multimap:AddPair()

Adds a new pair of values under a given key, replacing any existing value pair.

Multimap:AddPair( "Cake", "Delicious", 100 )
Multimap:AddPair( "Cake", "I would like more.", 200 )

This can be useful to store things such as weightings against values in the multimap.

Multimap:AsTable()

Returns the multimap as a more standard table structure of keys to table of values.

PrintTable( Multimap:AsTable() )
--[[
{
    Cake = {
        [ 1 ] = "Delicious",
        [ 2 ] = "I would like more."
    }
}
]]

Note that this omits any secondary values associated with keys.

Multimap:Get()

Returns a table containing all values mapped against the given key. Avoid modifying this table.

local Values = Multimap:Get( "Cake" )
--> { "Delicious", "I would like more." }

Multimap:GetPairs()

Returns a map of pairs under the given key. Avoid modifying this map.

local Pairs = Multimap:GetPairs( "Cake" )
--> Map( { [ "Delicious" ] = 100, [ "I would like more." ] = 200 } )

Multimap:GetPairValue()

Returns the value associated with the given key-value pair.

local Weighting = Multimap:GetPairValue( "Cake", "Delicious" )
--> 100

Multimap:GetCount()

Returns the number of key-value pairs in the multimap, not the number of keys.

local Count = Multimap:GetCount()
--> 2

Multimap:Iterate() and Multimap:IterateBackwards()

When iterating, the values will be the same as calling Multimap:Get(), so a table of all values mapped to the key.

for Key, Values in Multimap:Iterate() do
    -- Key = Cake
    LuaPrint( Key )
    -- Values = { "Delicious", "I would like more." }
    PrintTable( Values )
end

Multimap:RemoveKeyValue()

Removes a key-value pair from the multimap, returning true if the pair existed and was removed, or false otherwise.

local Removed = Multimap:RemoveKeyValue( "Cake", "I would like more." )
--> true
Clone this wiki locally