2010-10-13 16 views
6

द्वारा लिंक खोज परिणाम मेरे पास एक ऑब्जर्जेबल कोलेक्शन है, जिसमें Person ऑब्जेक्ट है। मेरे पास मेरे एप्लिकेशन में एक खोज सुविधा है, और शीर्ष पर सबसे प्रासंगिक परिणाम प्रदर्शित करना चाहते हैं। ऐसा करने का सबसे प्रभावी तरीका क्या होगा?निकटतम मिलान

var results = (from s in userList 
       where s.Name.Contains(query) 
       select s).ToList(); 

यह ठीक काम करता है, लेकिन परिणाम एक ही क्रम में वे userList के भीतर प्रदर्शित में आदेश दिया जाता है: मेरे वर्तमान खोज विधि केवल contains प्रणाली को बुलाती है। अगर मैं Pete के लिए खोज, तो यह पहले Pete प्रदर्शित करना चाहिए, तो Peter तो Peter Smith आदि .. यह बहुत जटिल के रूप में यह केवल कुछ हजार (अधिकतम) परिणामों के साथ काम किया जाएगा नहीं है। मेरा बेवकूफ दृष्टिकोण सबसे पहले s.Name == query करना था, उस आइटम को प्रदर्शित करें (यदि कोई है), तो s.Name.Contains(query) प्रदर्शन करें, मिलान किए गए आइटम को हटाएं और इसे पिछले मिलान किए गए परिणाम में जोड़ें। हालांकि, यह जगह पर थोड़ा सा लगता है और क्या कोई बेहतर तरीका है? धन्यवाद (पीएस - केवल नाम का उपयोग खोज में किया जाएगा, और मैं एसक्यूएल विधियों का उपयोग नहीं कर सकता)

उत्तर

10

आप एक एकल दिनचर्या बना सकते हैं जो एक नाम और क्वेरी स्ट्रिंग प्रदान करता है, और एक पूर्णांक मान देता है।

एक बार जब आप किया है कि, बस द्वारा आदेश के माध्यम से वापसी:

int QueryOrder(string query, string name) 
{ 
    if (name == query) 
     return -1; 
    if (name.Contains(query)) 
     return 0; 

    return 1; 
} 

तब कार्य करें:

var results = userList.OrderBy(s => QueryOrder(query, s.Name)); 

इस विधि की अच्छी बात यह है कि, बाद में, आप नियमित विस्तार कर सकता है प्रदान करना है अधिक जानकारी, आपको एक मैच के "अच्छे" से कैसे क्रमबद्ध करने की अनुमति देता है। उदाहरण के लिए, "पीट" -> "पीटर" शायद "पीट" -> "पीटर स्मिथ" से बेहतर मैच है, इसलिए आप अपने तर्क को विभिन्न विकल्पों के लिए एक अलग मूल्य वापस कर सकते हैं ...

यदि आप "गैर-पीट" मैचों को हटाने की आवश्यकता है, आप एक खंड के साथ भी बाहर निकल सकते हैं।

+0

धन्यवाद है, मैं सिर्फ इस परीक्षण किया है और यह पूरी तरह से काम करने लगता है। अच्छा और सरल :) – Brap

7

आपको समानता के लिए कुछ प्रकार के स्कोरिंग फ़ंक्शन की आवश्यकता है। तो फिर तुम सिर्फ कर सकते हैं:

from s in userList 
let score = Score(s, query) 
where score > 80 
orderby score descending 
select s; 

अब यह आपके उदाहरण बिल्कुल से स्पष्ट नहीं है (यह एक स्कोरिंग समारोह जो 0-100, जहां 100 एक आदर्श मैच है जो मूल्य देता है मान रहा है।) क्या स्कोरिंग समारोह होना चाहिए - यह है कि आप बाहर काम करने के लिए :)

+0

मदद के लिए धन्यवाद। मैं एक हैमिंग दूरी विधि के लिए जा रहा था, लेकिन यह इस समस्या के लिए थोड़ा अधिक और अक्षम हो सकता है। – Brap

0
var results = (from s in userList 
       where s.Name.Contains(query) 
       orderBy s.Length 
       select s).ToList(); 
संबंधित मुद्दे