// *************************************************************************** // // Delphi MVC Framework // // Copyright (c) 2010-2022 Daniele Teti and the DMVCFramework Team // // https://github.com/danieleteti/delphimvcframework // // *************************************************************************** // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // *************************************************************************** } unit MVCFramework.MultiMap; {$I dmvcframework.inc} interface uses System.Generics.Collections; type IMVCMultiMap = interface ['{8D762DCE-3DB0-42BB-973C-68C49997606D}'] procedure Add(const AKey: TKey; const AValue: TVal); function GetItems(const AKey: TKey): TList; function Contains(const AKey: TKey): Boolean; function Keys: TArray; procedure Remove(const AKey: String); procedure Clear; end; IMVCInterfaceMultiMap = interface(IMVCMultiMap) ['{90534C2B-7E93-4907-81CE-4CF6CAE63D50}'] end; TMVCInterfaceMultiMap = class(TInterfacedObject, IMVCInterfaceMultiMap) private FMultiMap: TObjectDictionary>; public constructor Create(AOwnsValues: Boolean = True); virtual; destructor Destroy; override; procedure Add(const AKey: String; const AValue: TVal); function GetItems(const AKey: String): TList; function Contains(const AKey: String): Boolean; function Keys: TArray; procedure Remove(const AKey: String); procedure Clear; end; IMVCObjectMultiMap = interface(IMVCMultiMap) ['{1F6A6826-0759-488A-AEFC-A068AD5BB5DE}'] end; TMVCObjectMultiMap = class(TInterfacedObject, IMVCObjectMultiMap) private FMultiMap: TObjectDictionary>; public constructor Create(AOwnsValues: Boolean = True); virtual; destructor Destroy; override; procedure Add(const AKey: String; const AValue: TVal); function GetItems(const AKey: String): TList; function Contains(const AKey: String): Boolean; function Keys: TArray; procedure Remove(const AKey: String); procedure Clear; end; implementation uses System.SysUtils; { TMVCObjectMultiMap } procedure TMVCObjectMultiMap.Add(const AKey: String; const AValue: TVal); var lList: TObjectList; begin if not FMultiMap.TryGetValue(AKey, lList) then begin lList := TObjectList.Create(True); FMultiMap.Add(AKey, lList); end; lList.Add(AValue); end; procedure TMVCObjectMultiMap.Clear; begin FMultiMap.Clear; end; function TMVCObjectMultiMap.Contains(const AKey: String): Boolean; begin Result := FMultiMap.ContainsKey(AKey); end; constructor TMVCObjectMultiMap.Create(AOwnsValues: Boolean); var lDictOwnerships: TDictionaryOwnerships; begin inherited Create; lDictOwnerships := []; if AOwnsValues then lDictOwnerships := lDictOwnerships + [doOwnsValues]; FMultiMap := TObjectDictionary < String, TObjectList < TVal >>.Create(lDictOwnerships); end; destructor TMVCObjectMultiMap.Destroy; begin FMultiMap.Free; inherited; end; function TMVCObjectMultiMap.GetItems(const AKey: String): TList; var lOutput: TObjectList; begin Result := nil; if FMultiMap.TryGetValue(AKey, lOutput) then Result := lOutput; end; function TMVCObjectMultiMap.Keys: TArray; begin Result := FMultiMap.Keys.ToArray; end; procedure TMVCObjectMultiMap.Remove(const AKey: String); begin FMultiMap.Remove(AKey); end; { TMVCInterfaceMultiMap } procedure TMVCInterfaceMultiMap.Add(const AKey: String; const AValue: TVal); var lList: TList; begin if not FMultiMap.TryGetValue(AKey, lList) then begin lList := TList.Create; FMultiMap.Add(AKey, lList); end; lList.Add(AValue); end; procedure TMVCInterfaceMultiMap.Clear; begin FMultiMap.Clear; end; function TMVCInterfaceMultiMap.Contains(const AKey: String): Boolean; begin Result := FMultiMap.ContainsKey(AKey); end; constructor TMVCInterfaceMultiMap.Create(AOwnsValues: Boolean); var lDictOwnerships: TDictionaryOwnerships; begin inherited Create; lDictOwnerships := []; if AOwnsValues then lDictOwnerships := lDictOwnerships + [doOwnsValues]; FMultiMap := TObjectDictionary < String, TList < TVal >>.Create(lDictOwnerships); end; destructor TMVCInterfaceMultiMap.Destroy; begin FMultiMap.Free; inherited; end; function TMVCInterfaceMultiMap.GetItems(const AKey: String): TList; var lOutput: TList; begin Result := nil; if FMultiMap.TryGetValue(AKey, lOutput) then Result := lOutput; end; function TMVCInterfaceMultiMap.Keys: TArray; begin Result := FMultiMap.Keys.ToArray; end; procedure TMVCInterfaceMultiMap.Remove(const AKey: String); begin FMultiMap.Remove(AKey); end; end.