2010-10-23 18 views
5

मैं एक शब्दकोश चाहता हूं जो खोज कुंजी नहीं मिलने पर डिफ़ॉल्ट मान देता है। प्रलेखन से पढ़ना:डेल्फी जेनेरिक> शब्दकोश डिफ़ॉल्ट मान के साथ

जेनिक्स.कोलेक्शन.डर्नी [...] यह कक्षा मैपिंग [...] और प्रारंभिक सामग्री प्रदान करती है।

1 - कैसे? क्या यह एला पायथन करने का कोई तरीका है: {1: 'एक'; 2: 'दो'}?

जेनिक्स.कोलेक्शन .TDictionary.TryGetValue [...] यदि दिया गया कुंजी शब्दकोश में है और मूल्य में अपना मान प्रदान करता है तो TryGetValue सत्य लौटाता है। अन्यथा, यह झूठा रिटर्न देता है और मान डिफ़ॉल्ट मान प्रकार के स्तर पर सेट होता है।

2 - मैं यह डिफ़ॉल्ट मान कैसे सेट कर सकता हूं? मुझे एक कन्स्ट्रक्टर नहीं मिल रहा है (हो सकता है कि मैंने अभी गलत जगह पर खोज की हो। मुझे कुछ ऐसा करने की उम्मीद है "कन्स्ट्रक्टर बनाएं (डिफॉल्ट वैल्यू: टीवीएयू);")

तो मैं अपना खुद का कार्यान्वयन करने की कोशिश कर रहा हूं (हो सकता है आवश्यक नहीं है ऊपर देखें।): (! समीक्षा और सुझावों का स्वागत है)

कोड है:

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; 

और परीक्षण कर रहे हैं:

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. 

कतई नहीं है कि पूरा हो रहा है मैं इंडेक्सर ऑपरेटर भी काम करना चाहता हूं (अंतिम परीक्षण देखें)। यह संभव है? क्या भी लागू किया जाना चाहिए?

क्या यह कार्यान्वयन M_DefaultValue (मैं डेल्फी के लिए नया हूं) को लीक करता है। मैं कुछ नहीं कर सकता M_DefaultValue. विनाशक में फ्री (कन्स्ट्रक्टर बाधा के कारण इतना लचीला नहीं है) यहां क्या किया जा सकता है?

अग्रिम धन्यवाद,

फ्रांसिस

+0

आपने वर्तमान में डेल्फी में एक बहुत अच्छा सवाल उठाया है, हमें दो शब्दकोश लुकअप करना है। PHP के बारे में भी यही सच है। –

उत्तर

1

यह सब कोड अपने आप को लिखने से पहले, आप DeHL library में सामान्य वर्गों को देखने के लिए चाहते हो सकता है।

प्रकार समर्थन अवधारणा है कि प्रत्येक में निर्मित डेल्फी प्रकार (संग्रह में चूक के रूप में इस्तेमाल) के लिए डिफ़ॉल्ट "समर्थन वर्गों" का एक सेट को परिभाषित करता है:

यह इस का समर्थन करता है। कस्टम "टाइप समर्थन" कक्षाएं के लिए आपके कस्टम डेटा प्रकारों के लिए पंजीकृत की जा सकती हैं।

--jeroen

+0

मुझे उम्मीद है कि यह कुछ अलग है: डिफ़ॉल्ट तुलनाकर्ता और जैसे, "कुंजी मौजूद नहीं" के मामले में किसी शब्दकोश से डिफ़ॉल्ट मान नहीं दिया गया है। –

+0

आपका उत्तर उस मित्रवत नहीं है। लेखक का प्रश्न मुख्य विचार दो लुकअप से बचने के लिए था: पहला लुकअप यह जांच नहीं करता है कि मूल्य मौजूद है या नहीं, और वास्तव में मूल्य को वापस करने के लिए दूसरा लुकअप। यदि आप एक कोड उदाहरण के साथ एक स्पष्ट सीधा जवाब प्रदान करते, तो यह उपयोगी होता, उदाहरण के लिए TryGetValue का उपयोग कैसे करें और प्रत्येक प्रकार का एक डिफ़ॉल्ट मान है जिसे बदला नहीं जा सकता है, उदाहरण के लिए, इंटीजर 0 है, स्ट्रिंग है '', आदि –

+0

@ मैक्सिममासिटिन उपयोगकर्ता फ्रैंकिस ने कभी जवाब नहीं दिया (2010 में पिछली बार सक्रिय) और एक एसओ सवाल में कुछ सवाल उठाए, यह समझना मुश्किल है कि उसका ठोकर क्या है। तो - प्रश्न में कोड की स्थिति दी गई - मुझे लगता है कि अच्छी स्थिर लाइब्रेरी कोड लिखना प्रमुख मुद्दा था और उसके बाद - वर्तमान - डीएचएल लाइब्रेरी। आजकल मैं http://spring4d.org पर निर्देशित करूंगा –

0

मुख्य समस्या> GetItem TDictionary < में आभासी नहीं है। इसे

property Items[const Key: K]: V read GetValueOf write SetItem; default; 

आपकी कक्षा में जोड़कर हल किया जा सकता है।

बीटीडब्ल्यू, विनाशकों को अतिरंजित किया जाना चाहिए, पुन: उत्पादित नहीं किया जाना चाहिए ताकि जब आप इसे उच्च श्रेणीबद्ध वर्ग के रूप में परिभाषित चर में संग्रहीत करते हैं तो यह सही विनाशक कहता है। यह सिर्फ एक सर्वोत्तम अभ्यास है, लेकिन इस विशिष्ट मामले में आइटम [] काम नहीं करेगा जैसा कि आप चाहते हैं।

भगवान आपको आशीर्वाद देते हैं।

संबंधित मुद्दे