Tôi muốn có từ điển trả về giá trị mặc định khi không tìm thấy khóa tìm kiếm. Đọc từ tài liệu:Delphi Generics> Từ điển với giá trị mặc định
Generics.Collections.Tdictionary […] Lớp này cung cấp ánh xạ […] và nội dung ban đầu.
1 - Làm cách nào? Có cách nào để làm điều đó ala Python: {1: ‘one’; 2: ’hai’}?
Generics.Collections.TDictionary.TryGetValue [...] TryGetValue trả về true nếu khóa đã cho nằm trong từ điển và cung cấp giá trị của nó trong Giá trị. Nếu không, nó trả về false và Value được đặt thành kiểu giá trị mặc định của Tvalue.
2 - Làm cách nào tôi có thể đặt giá trị mặc định này? Tôi không thể tìm thấy một nhà xây dựng (có thể là tôi vừa tìm kiếm ở nơi sai. Tôi đang mong đợi một cái gì đó như "constructor Create (DefaultValue: TValue);")
Vì vậy, tôi đang cố gắng thực hiện của riêng tôi (có thể là không cần thiết Xem ở trên.): (! đánh giá và đề nghị được hoan nghênh)
mã này là:
unit Util;
interface
uses
Generics.collections;
type
//
// Dictionary with default response
//
TDefaultDictonary<K, V> = class(TObjectDictionary<K, V>)
private
M_DefaultValue : V;
public
constructor Create(Defaultvalue : V);
destructor Destroy; reintroduce;
function GetDefaultValue : V;
function TryGetValue(const Key: K; out Value: V): Boolean;
function GetValueOf(const Key: K) : V;
end;
implementation
//
// Contructor and destructor
//
constructor TDefaultDictonary<K, V>.Create(Defaultvalue : V);
begin
inherited Create;
M_DefaultValue := Defaultvalue;
end;
destructor TDefaultDictonary<K, V>.Destroy;
begin
inherited Destroy;
end;
//
// Get the default Value
//
function TDefaultDictonary<K, V>.GetDefaultValue : V;
begin
Result := M_DefaultValue;
end;
//
// Try to get a value from the dictionary for the given key.
//
// If the value is found then "Value" holds it and the function returns true.
// If the value is not found then "Value" holds the default value and the
// function returns false.
//
function TDefaultDictonary<K, V>.TryGetValue(const Key: K; out Value: V): Boolean;
var
IsKeyFound : boolean;
DictVal : V;
begin
IsKeyFound := inherited TryGetValue(Key, DictVal);
if not IsKeyFound then begin
DictVal := M_DefaultValue;
end;
// Outputs:
Value := DictVal;
Result := IsKeyFound;
end;
//
// Get a value from the dictionary for the given key.
//
// If the value is found then the function returns it.
// If the value is not found the function returns the default value.
//
function TDefaultDictonary<K, V>.GetValueOf(const Key: K) : V;
var
DictVal : V;
begin
TryGetValue(Key, DictVal);
Result := DictVal;
end;
và các bài kiểm tra bao gồm:
unit Test_Utils;
{
Test the TDefaultDictionary functionality
}
interface
uses
Sysutils, Math, TestFramework, Util;
type
TestUtil = class(TTestCase)
public
procedure SetUp; override;
procedure TearDown; override;
published
procedure TestDefaultDictionaryGetDefaultResponse;
procedure TestDefaultDictionaryExistingKey;
procedure TestDefaultDictionaryNotExistingKey;
end;
implementation
procedure TestUtil.SetUp;
begin
end;
procedure TestUtil.TearDown;
begin
end;
procedure TestUtil.TestDefaultDictionaryGetDefaultResponse;
var
dd : TDefaultDictonary<integer, string>;
begin
dd := TDefaultDictonary<integer, string>.Create('Default response');
checkEquals('Default response', dd.GetDefaultValue);
dd.Free;
end;
procedure TestUtil.TestDefaultDictionaryExistingKey;
var
dd : TDefaultDictonary<integer, string>;
outVal : string;
isKeyFound : boolean;
begin
dd := TDefaultDictonary<integer, string>.Create('Default response');
dd.Add(1, 'My one');
checkEquals(1, dd.Count,
'One element as count');
isKeyFound := dd.TryGetValue(1, outVal);
check(isKeyFound,
'Key not found by TryGetValue');
checkEquals('My one', outVal,
'Value given by TryGetValue');
checkEquals('My one', dd[1],
'Value given by indexing as array');
dd.Free;
end;
procedure TestUtil.TestDefaultDictionaryNotExistingKey;
var
dd : TDefaultDictonary<integer, string>;
outVal : string;
isKeyFound : boolean;
begin
dd := TDefaultDictonary<integer, string>.Create('Default response');
dd.Add(1, 'one');
isKeyFound := dd.TryGetValue(2, outVal);
check(not isKeyFound,
'Key should not be found by TryGetValue');
checkEquals('Default response', outVal,
'Default Value given by TryGetValue');
checkEquals('Default response', dd.GetValueOf(2),
'Default Value given by indexing as array');
//
// It is possible to oveload the indexer operator?
// Please review or delete me !
//
//checkEquals('Default response', dd[2],
// 'Value given by indexing as array');
//
dd.Free;
end;
initialization
RegisterTest(TestUtil.Suite);
end.
Đó là xa hoàn thành. Tôi muốn có toán tử lập chỉ mục làm việc (xem thử nghiệm cuối cùng). Điều đó là có thể? Điều gì cần được triển khai?
Triển khai này có rò rỉ M_DefaultValue (Tôi mới đến Delphi) hay không. Tôi không thể làm một cái gì đó M_DefaultValue.Free trong destructor (không phải là quá linh hoạt do hạn chế constructor) Điều gì có thể được thực hiện ở đây?
Cảm ơn trước,
Francis
Bạn đã nêu ra một câu hỏi rất hay, vì hiện tại, ở Delphi, chúng tôi phải thực hiện hai tra cứu từ điển. Điều này cũng đúng về PHP. –