/// <summary> /// Atomically updates an existing item, unless it doesn't exist, in which case /// it is ignored /// </summary> /// <remarks>Null is not allowed for a Key or a Value</remarks> /// <param name="key">Key</param> /// <param name="value">Value</param> /// <exception cref="ArgumentNullException">Throws ArgumentNullException the value is null</exception> /// <returns>New Map with the item added</returns> public Map <K, V> TrySetItem(K key, V value) { if (isnull(key)) { return(this); } return(SetRoot(MapModule.TrySetItem(Root, key, value, Comparer <K> .Default))); }
/// <summary> /// Atomically adds a new item to the map. /// If the key already exists, the new item replaces it. /// </summary> /// <remarks>Null is not allowed for a Key or a Value</remarks> /// <param name="key">Key</param> /// <param name="value">Value</param> /// <exception cref="ArgumentNullException">Throws ArgumentNullException the key or value are null</exception> /// <returns>New Map with the item added</returns> public Map <K, V> AddOrUpdate(K key, V value) { if (isnull(key)) { throw new ArgumentNullException(nameof(key)); } return(SetRoot(MapModule.AddOrUpdate(Root, key, value, Comparer <K> .Default))); }
/// <summary> /// Atomically updates an existing item /// </summary> /// <remarks>Null is not allowed for a Key or a Value</remarks> /// <param name="key">Key</param> /// <param name="value">Value</param> /// <exception cref="ArgumentNullException">Throws ArgumentNullException the key or value are null</exception> /// <returns>New Map with the item added</returns> public Map <K, V> SetItem(K key, V value) { if (key == null) { throw new ArgumentNullException(nameof(key)); } return(SetRoot(MapModule.SetItem(Root, key, value, Comparer <K> .Default))); }
/// <summary> /// Atomically removes a set of keys from the map /// </summary> /// <param name="keys">Keys to remove</param> /// <returns>New map with the items removed</returns> public Map <K, V> RemoveRange(IEnumerable <K> keys) { var self = Root; foreach (var key in keys) { self = MapModule.Remove(self, key, Comparer <K> .Default); } return(SetRoot(self)); }
/// <summary> /// Retrieve a value from the map by key, map it to a new value, /// put it back. If it doesn't exist, add a new one based on None result. /// </summary> /// <param name="key">Key to find</param> /// <exception cref="ArgumentNullException">Throws ArgumentNullException if None is null</exception> /// <exception cref="Exception">Throws Exception if Some returns null</exception> /// <returns>New map with the mapped value</returns> public Map <K, V> AddOrUpdate(K key, Func <V, V> Some, V None) { if (isnull(None)) { throw new ArgumentNullException(nameof(None)); } return(isnull(key) ? this : match(MapModule.TryFind(Root, key, Comparer <K> .Default), Some: x => SetItem(key, Some(x)), None: () => Add(key, None))); }
/// <summary> /// Retrieve a range of values /// </summary> /// <param name="keyFrom">Range start (inclusive)</param> /// <param name="keyTo">Range to (inclusive)</param> /// <exception cref="ArgumentNullException">Throws ArgumentNullException the keyFrom or keyTo are null</exception> /// <returns>Range of values</returns> public IEnumerable <V> FindRange(K keyFrom, K keyTo) { if (isnull(keyFrom)) { throw new ArgumentNullException(nameof(keyFrom)); } if (isnull(keyTo)) { throw new ArgumentNullException(nameof(keyTo)); } return(Comparer <K> .Default.Compare(keyFrom, keyTo) > 0 ? MapModule.FindRange(Root, keyTo, keyFrom, Comparer <K> .Default) : MapModule.FindRange(Root, keyFrom, keyTo, Comparer <K> .Default)); }
/// <summary> /// Atomically sets a series of items using the Tuples provided If any of the /// items don't exist then they're silently ignored. /// </summary> /// <param name="items">Items to set</param> /// <returns>New map with the items set</returns> public Map <K, V> TrySetItems(IEnumerable <Tuple <K, V> > items) { var self = Root; foreach (var item in items) { if (isnull(item.Item1)) { continue; } self = MapModule.TrySetItem(self, item.Item1, item.Item2, Comparer <K> .Default); } return(SetRoot(self)); }
/// <summary> /// Atomically sets a series of items using the KeyValuePairs provided. If any of the /// items don't exist then they're silently ignored. /// </summary> /// <param name="items">Items to set</param> /// <returns>New map with the items set</returns> public Map <K, V> TrySetItems(IEnumerable <KeyValuePair <K, V> > items) { var self = Root; foreach (var item in items) { if (item.Key == null) { continue; } self = MapModule.TrySetItem(self, item.Key, item.Value, Comparer <K> .Default); } return(SetRoot(self)); }
/// <summary> /// Atomically sets a series of items using the Tuples provided. /// </summary> /// <param name="items">Items to set</param> /// <exception cref="ArgumentException">Throws ArgumentException if any of the keys aren't in the map</exception> /// <returns>New map with the items set</returns> public Map <K, V> SetItems(IEnumerable <Tuple <K, V> > items) { if (items == null) { return(this); } var self = Root; foreach (var item in items) { if (item.Item1 == null) { continue; } self = MapModule.SetItem(self, item.Item1, item.Item2, Comparer <K> .Default); } return(SetRoot(self)); }
/// <summary> /// Atomically adds a range of items to the map. /// </summary> /// <remarks>Null is not allowed for a Key or a Value</remarks> /// <param name="range">Range of tuples to add</param> /// <exception cref="ArgumentException">Throws ArgumentException if any of the keys already exist</exception> /// <exception cref="ArgumentNullException">Throws ArgumentNullException the keys or values are null</exception> /// <returns>New Map with the items added</returns> public Map <K, V> AddRange(IEnumerable <Tuple <K, V> > range) { if (range == null) { return(this); } var self = Root; foreach (var item in range) { if (isnull(item.Item1)) { throw new ArgumentNullException(nameof(item.Item1)); } self = MapModule.Add(self, item.Item1, item.Item2, Comparer <K> .Default); } return(SetRoot(self)); }
/// <summary> /// Atomically adds a range of items to the map. If any of the keys exist already /// then they're replaced. /// </summary> /// <remarks>Null is not allowed for a Key or a Value</remarks> /// <param name="range">Range of KeyValuePairs to add</param> /// <exception cref="ArgumentNullException">Throws ArgumentNullException the keys or values are null</exception> /// <returns>New Map with the items added</returns> public Map <K, V> AddOrUpdateRange(IEnumerable <KeyValuePair <K, V> > range) { if (range == null) { return(this); } var self = Root; foreach (var item in range) { if (isnull(item.Key)) { throw new ArgumentNullException(nameof(item.Key)); } self = MapModule.AddOrUpdate(self, item.Key, item.Value, Comparer <K> .Default); } return(SetRoot(self)); }
/// <summary> /// Retrieve a value from the map by key, map it to a new value, /// put it back. If it doesn't exist, add a new one based on None result. /// </summary> /// <param name="key">Key to find</param> /// <exception cref="Exception">Throws Exception if None returns null</exception> /// <exception cref="Exception">Throws Exception if Some returns null</exception> /// <returns>New map with the mapped value</returns> public Map <K, V> AddOrUpdate(K key, Func <V, V> Some, Func <V> None) => isnull(key) ? this : match(MapModule.TryFind(Root, key, Comparer <K> .Default), Some: x => SetItem(key, Some(x)), None: () => Add(key, None()));
/// <summary> /// Atomically sets an item by first retrieving it, applying a map, and then putting it back. /// Calls the None delegate to return a new map if the item can't be found /// </summary> /// <remarks>Null is not allowed for a Key or a Value</remarks> /// <param name="key">Key</param> /// <param name="Some">delegate to map the existing value to a new one before setting</param> /// <param name="None">delegate to return a new map if the item can't be found</param> /// <exception cref="Exception">Throws Exception if Some returns null</exception> /// <exception cref="Exception">Throws Exception if None returns null</exception> /// <returns>New map with the item set</returns> public Map <K, V> TrySetItem(K key, Func <V, V> Some, Func <Map <K, V>, Map <K, V> > None) => isnull(key) ? this : match(MapModule.TryFind(Root, key, Comparer <K> .Default), Some: x => SetItem(key, Some(x)), None: () => None(this));
/// <summary> /// Convert a LanguageExt Map (Map K V) into an F# Map /// </summary> public static FSharpMap <K, V> ToFSharp <K, V>(this Map <K, V> map) => MapModule.OfSeq(map.AsEnumerable().Map(item => Tuple(item.Key, item.Value)));
public IEnumerable <IMapItem <K, V> > AsEnumerable() => MapModule.AsEnumerable(this);
/// <summary> /// Returns true if a Key/Value pair exists in the map /// </summary> /// <param name="pair">Pair to find</param> /// <returns>True if exists, false otherwise</returns> public bool Contains(KeyValuePair <K, V> pair) => match(MapModule.TryFind(Root, pair.Key, Comparer <K> .Default), Some: v => ReferenceEquals(v, pair.Value), None: () => false);
/// <summary> /// Atomically removes an item from the map /// If the key doesn't exists, the request is ignored. /// </summary> /// <param name="key">Key</param> /// <returns>New map with the item removed</returns> public Map <K, V> Remove(K key) => isnull(key) ? this : SetRoot(MapModule.Remove(Root, key, Comparer <K> .Default));
/// <summary> /// Convert a LanguageExt Map into an F# Map /// </summary> public static FSharpMap <K, V> fs <K, V>(IImmutableDictionary <K, V> map) => MapModule.OfSeq(List.map(map, kv => Tuple.Create(kv.Key, kv.Value)));
public static Map <K, U> Map <K, V, U>(this Map <K, V> self, Func <K, V, U> mapper) => new Map <K, U>(MapModule.Map(self.Value.Root, mapper), self.Value.Rev);
/// <summary> /// Atomically sets an item by first retrieving it, applying a map, and then putting it back. /// Silently fails if the value doesn't exist /// </summary> /// <param name="key">Key to set</param> /// <param name="Some">delegate to map the existing value to a new one before setting</param> /// <exception cref="Exception">Throws Exception if Some returns null</exception> /// <exception cref="ArgumentNullException">Throws ArgumentNullException the key or value are null</exception> /// <returns>New map with the item set</returns> public Map <K, V> TrySetItem(K key, Func <V, V> Some) => key == null ? this : match(MapModule.TryFind(Root, key, Comparer <K> .Default), Some: x => SetItem(key, Some(x)), None: () => this);
/// <summary> /// Retrieve a value from the map by key /// </summary> /// <param name="key">Key to find</param> /// <returns>Found value</returns> public Option <V> Find(K key) => isnull(key) ? None : MapModule.TryFind(Root, key, Comparer <K> .Default);
public static Map <OrdK, K, U> Map <OrdK, K, V, U>(this Map <OrdK, K, V> self, Func <K, V, U> mapper) where OrdK : struct, Ord <K> => new Map <OrdK, K, U>(MapModule.Map(self.Value.Root, mapper), self.Value.Rev);
/// <summary> /// GetEnumerator - IEnumerable interface /// </summary> IEnumerator IEnumerable.GetEnumerator() => MapModule.AsEnumerable(this).GetEnumerator();
/// <summary> /// Retrieve a value from the map by key and pattern match the /// result. /// </summary> /// <param name="key">Key to find</param> /// <returns>Found value</returns> public R Find <R>(K key, Func <V, R> Some, Func <R> None) => isnull(key) ? None() : match(MapModule.TryFind(Root, key, Comparer <K> .Default), Some, None);
IEnumerator <KeyValuePair <K, V> > IEnumerable <KeyValuePair <K, V> > .GetEnumerator() => (from x in MapModule.AsEnumerable(this) select new KeyValuePair <K, V>(x.Key, x.Value)).GetEnumerator();
/// <summary> /// Retrieve a value from the map by key, map it to a new value, /// put it back. /// </summary> /// <param name="key">Key to set</param> /// <exception cref="ArgumentException">Throws ArgumentException if the item isn't found</exception> /// <exception cref="Exception">Throws Exception if Some returns null</exception> /// <returns>New map with the mapped value</returns> public Map <K, V> SetItem(K key, Func <V, V> Some) => isnull(key) ? this : match(MapModule.TryFind(Root, key, Comparer <K> .Default), Some: x => SetItem(key, Some(x)), None: () => raise <Map <K, V> >(new ArgumentException("Key not found in Map")));