Reputation: 11227
It could very well be that the answer to this question is an obvious and resounding "there's no such thing", but I'll give it a shot: Is there a functional map-like data structure that is more efficient than a standard map when the keys have an arbitrary, often very big, size?
For the sake of concreteness, consider the Haskell type
(Ord k) => Map [k] v
in which lookups can take a very long time if lists need to be compared down to a deep level. I guess hashing is also out of the question due to the arbitrary length of the lists. I still can't help but think there could be a clever data structure out there.
Upvotes: 3
Views: 510
Reputation: 89123
Here's one:
module ListMap where
import Data.Map as M
data ListMap k v = ListMap { ifEmpty :: Maybe v, ifFull :: Maybe k (ListMap k v) }
empty :: ListMap k v
empty = ListMap Nothing M.empty
singleton :: [k] -> v -> ListMap k v
singleton [] v = ListMap.empty { ifEmpty = Just v }
singleton (k:ks) v = ListMap.empty { ifFull = M.singleton k (ListMap.singleton ks v) }
lookup :: Ord k => [k] -> ListMap k v -> Maybe v
lookup [] lm = ifEmpty lm
lookup (k:ks) lm = M.lookup k (ifFull lm) >>= ListMap.lookup ks
insert :: Ord k => [k] -> v -> ListMap k v -> ListMap k v
insert [] v lm = lm { ifEmpty = Just v }
insert (k:ks) v lm = lm { ifFull = M.alter (Just . insertion) k (ifFull lm) }
where insertion = maybe (ListMap.singleton ks v) (ListMap.insert ks v)
It's essentially creating a prefix tree on the list elements so you only compare as far as necessary.
Upvotes: 1
Reputation: 33103
A trie?
If you have two long keys that are almost identical, a Map will compare them both from the beginning, but a trie will only compare the suffixes that haven't already been eliminated by previous comparisons (if you see what I mean). So a trie would be more time-efficient in that situation.
Tries can be optimised in various ways, and you might also want to look at ternary trees.
Upvotes: 3
Reputation: 137997
Is hashing out of the question? There's no prefix of the key structure that can be computed efficiently?
If not, how about a hashmap? Take the very big key, reduce it to something very small, use that as an index into a structure.
Upvotes: 6