2011-10-29 11 views
5

मेरे पास एक मृत सरल सामान्य लिस्प प्रश्न है: स्ट्रिंग्स की सूची से डुप्लिकेट को हटाने का बेवकूफ तरीका क्या है?किसी सूची से डुप्लिकेट स्ट्रिंग को हटाएं

remove-duplicates काम करता है के रूप में मैं संख्या के लिए उम्मीद थी, लेकिन तार के लिए नहीं:

* (remove-duplicates '(1 2 2 3)) 

(1 2 3) 

* (remove-duplicates '("one" "two" "two" "three")) 

("one" "two" "two" "three") 

मैं कुछ समझ में जो तार बराबर नहीं हैं वहाँ है, सबसे अधिक संभावना है क्योंकि हालांकि अनुमान लगा रहा हूँ "foo "और" foo "स्पष्ट रूप से समान हैं, वे वास्तव में स्मृति में विभिन्न संरचनाओं के संकेतक हैं। मुझे लगता है कि यहां मेरी उम्मीद सिर्फ सी हैंगओवर हो सकती है।

उत्तर

17

आपको हटाने-डुप्लीकेट बताएं कि इसे मूल्यों की तुलना कैसे की जानी चाहिए। डिफ़ॉल्ट रूप से, यह eql का उपयोग करता है, जो तारों के लिए पर्याप्त नहीं है। में के रूप में :test समारोह दर्रा:

(remove-duplicates your-sequence :test #'equal). 

(टिप्पणियों से प्रश्नों के उत्तरों संपादित करें): equal के लिए एक विकल्प के रूप में, आप इस उदाहरण में string= इस्तेमाल कर सकते हैं। यह भविष्यवाणी (एक तरह से) equal से कम सामान्य है और यह संभवतः (संभवतः, संभवतः, अंततः ...) हो सकती है। एक वास्तविक लाभ हो सकता है, कि string= आपको बता सकता है कर सकते हैं, यदि आप एक गलत मान पास:

(equal 1 "foo") 

खुशी से पैदावार nil, जबकि

(string= 1 "foo") 

एक type-error हालत देता है। नोट, हालांकि, कि

(string= "FOO" :FOO) 

पूरी तरह से अच्छी तरह से परिभाषित किया गया है (string= और उसके दोस्त "स्ट्रिंग designators" नहीं तार के रूप में परिभाषित कर रहे हैं), तो सुरक्षा टाइप केवल अब तक यहां जाना होगा।

मानक eql दूसरी तरफ, तारों की तुलना करने का लगभग सही तरीका कभी नहीं है। यदि आप जावा भाषा से परिचित हैं, eql== का उपयोग करते हुए equal (या string= इत्यादि) equals(Object) विधि को कॉल करते हुए सोचें। हालांकि eql कुछ प्रकार के आत्मनिरीक्षण (eq के विपरीत है, जो नहीं करता है), अधिकांश (गैर-संख्यात्मक) लिस्पी प्रकारों के लिए, eql पॉइंटर तुलना की तरह कुछ उबालता है, जो पर्याप्त नहीं है, यदि आप मूल्यों के आधार पर मूल्यों का भेद करना चाहते हैं वे वास्तव में क्या रखते हैं, न कि केवल स्मृति में जहां वे स्थित हैं। जबकि equal अधिक == जो __eq__ कॉल की तरह है

अधिक pythonic के लिए इच्छुक, eq (और गैर-संख्यात्मक प्रकार के लिए eql), अधिक is ऑपरेटर की तरह है।

+0

मैं इक्वाल के बजाय STRING = का उपयोग करने का लुत्फ उठाउंगा। – Vatine

+1

क्यों? अंतर क्या है? – rivasket

+0

STRING = CHAR का उपयोग कर वर्णों की तुलना करता है = जो [हाइपरस्पेक] (http://www.lispworks.com/documentation/HyperSpec/Body/f_chareq.htm#char-equal) के अनुसार "... ... सभी वर्ण हैं तो सत्य लौटाता है वही; अन्यथा, यह झूठा लौटाता है। यदि दो वर्ण किसी कार्यान्वयन-परिभाषित विशेषताओं में भिन्न होते हैं, तो वे char = "नहीं हैं। मुझे यकीन नहीं है कि कार्यान्वयन-परिभाषित व्यवहार का उपयोग करना बेहतर विकल्प है। –