2009-12-01 14 views
9

मैं क्रमबद्ध करना चाहते हैं का उपयोग कर छंटाई व्यक्ति की एक सूचीसी # - एक्सटेंशन विधि

List<Person> persons=new List<Person>(); 
persons.Add(new Person("Jon","Bernald",45000.89)); 
persons.Add(new Person("Mark","Drake",346.89)); 
persons.Add(new Person("Bill","Watts",456.899)); 

public enum CompareOptions 
{ 
    ByFirstName, 
    ByLastName, 
    BySalary 
} 

public enum SortOrder 
{ 
    Ascending, 
    Descending 
} 

के आधार पर लैम्ब्डा अभिव्यक्ति का उपयोग कर क्या छँटाई के लिए जाने का रास्ता है कहते हैं?

public static List<Person> SortPeople(this List<Person> lst, 
    CompareOptions opt1,SortOrder ord) 

     { 
      lst.Sort((p,op1,op2)=>{ how to apply lambda expression here}); 
     } 
+1

अच्छा प्रश्न है। आप विशेषज्ञों को कॉम्पैक्ट और पठनीय कोड का उत्पादन कर रहे हैं। हम सब इससे सीखते हैं। धन्यवाद!! – shahkalpesh

+0

मदद के लिए सभी को धन्यवाद – user215675

+0

@ शाहकालपेश, आपने भी मेरे पुराने प्रश्नों के लिए मेरी मदद की। मैं आपको एक बार फिर धन्यवाद देने का अवसर लेना चाहता हूं। – user215675

उत्तर

8

ऐसा लगता है कि जो एक Comparison<T> प्रतिनिधि लेता List<T> पर क्रमबद्ध विधि कॉल करने के प्रयास कर रहे हैं की तरह। इसके लिए थोड़ा सा काम करने की आवश्यकता होगी क्योंकि आपको पहले एक संगत तुलना फ़ंक्शन को परिभाषित करना होगा।

प्रथम चरण CompareOptions मूल्य

private static Comparison<Person> Create(CompareOptions opt) { 
    switch (opt) { 
    case CompareOptions.ByFirstName: (x,y) => x.FirstName.CompareTo(y.FirstName); 
    case CompareOptions.ByLastName: (x,y) => x.LastName.CompareTo(y.LastName); 
    case CompareOptions.BySalary: (x,y) => x.Salary - y.Salary; 
    default: throw new Exception(); 
    } 
} 

डिफ़ॉल्ट रूप से इस समारोह आरोही क्रम में सॉर्ट जाएगा के आधार पर एक तुलना समारोह लिखने के लिए है। यदि आप इसे उतरना चाहते हैं तो बस मूल्य को अस्वीकार करें। तो अब लिखित SortPeople निम्नलिखित द्वारा किया जा सकता

public static List<Person> SortPeople(
    this List<Person> list, 
    CompareOptions opt1, 
    SortOrder ord)) 
    var original = Create(opt1); 
    var comp = original; 
    if(ord == SortOrder.Descending) { 
    comp = (x,y) => -(orig(x,y)); 
    } 
    list.Sort(comp); 
} 

संपादित

संस्करण जो

public static List<Person> SortPeople(
    this List<Person> list, 
    CompareOptions opt1, 
    SortOrder ord)) 

    list.Sort((x,y) => { 
    int comp = 0; 
    switch (opt) { 
     case CompareOptions.ByFirstName: comp = x.FirstName.CompareTo(y.FirstName); 
     case CompareOptions.ByLastName: comp = x.LastName.CompareTo(y.LastName); 
     case CompareOptions.BySalary: comp = x.Salary.CompareTo(y.Salary); 
     default: throw new Exception(); 
    } 
    if (ord == SortOrder.Descending) { 
     comp = -comp; 
    } 
    return comp; 
    }); 
} 
+0

यह अच्छा और साफ है, लेकिन यह वास्तव में यह नहीं दिखाता है कि इसे लैम्ब्डा में कैसे किया जाए, ओपी ने यही पूछा। –

+0

@ रीड कॉपसी मैं इसे केवल एक लम्बा में करने की अनुशंसा नहीं करता, क्योंकि प्रत्येक तुलना सभी आईएफएस को पार कर जाएगी, न कि केवल सही समय के लिए सही लैम्ब्डा चुनने के लिए। – Wilhelm

+0

@ रीड, सच, मैंने शुद्ध लैम्ब्डा संस्करण को शामिल करने के लिए उत्तर अपडेट किया। – JaredPar

3

यह एक लैम्ब्डा में काम करने के लिए प्राप्त करने के लिए एक लैम्ब्डा में 100% किया जाता है, अभिव्यक्ति को Comparison<T> हस्ताक्षर बनाने की आवश्यकता है। इसमें 2 "व्यक्ति" उदाहरण होंगे। आप इस तरह कर सकता है:

public static void SortPeople(
    this List<Person> lst, CompareOptions opt1,SortOrder ord) 
{ 
    lst.Sort((left, right) => 
      { 
       int result; 
       // left and right are the two Person instances 
       if (opt1 == CompareOptions.Salary) 
       { 
        result = left.Salary.CompareTo(right.Salary); 
       } 
       else 
       { 
        string compStr1, compStr2; 
        if (opt1 == CompareOptions.FirstName) 
        { 
          compStr1 = left.FirstName; 
          compStr2 = right.FirstName; 
        } 
        else 
        { 
          compStr1 = left.LastName; 
          compStr2 = right.LastName; 
        } 
        result = compStr1.CompareTo(compStr2); 
       } 
       if (ord == SortOrder.Descending) 
        result *= -1; 
       return result; 
      }); 
} 
+0

एक्सटेंशन विधि को वापसी प्रकार शून्य होना आवश्यक है। –

+0

यह करता है।"रिटर्न परिणाम" सॉर्टिंग ऑर्डर लौटने पर संपीड़न है। विस्तार विधि सिर्फ {lst.Sort (...) है; } –

+0

नहीं, मैं बस इतना कह रहा हूं कि SortPeople विधि में वापसी प्रकार है जो यह वापस नहीं आता है, लेकिन मुझे लगता है कि आपने इसे सिर्फ अपने उदाहरण से कॉपी किया है ... –

2
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication2 
{ 
    class Program 
    { 
    static void Main(string[] args) 
    { 
     List<Person> persons = new List<Person>(); 
     persons.Add(new Person("Jon", "Bernald", 45000.89)); 
     persons.Add(new Person("Mark", "Drake", 346.89)); 
     persons.Add(new Person("Bill", "Watts", 456.899)); 

     persons.SortPeople(CompareOptions.ByFirstName, SortOrder.Ascending); 

     persons.ForEach(p => Console.WriteLine(p.ToString())); 

     persons.SortPeople(CompareOptions.ByFirstName, SortOrder.Descending); 

     persons.ForEach(p => Console.WriteLine(p.ToString())); 

     persons.SortPeople(CompareOptions.ByLastName, SortOrder.Ascending); 

     persons.ForEach(p => Console.WriteLine(p.ToString())); 

     persons.SortPeople(CompareOptions.ByLastName, SortOrder.Descending); 

     persons.ForEach(p => Console.WriteLine(p.ToString())); 

     persons.SortPeople(CompareOptions.BySalary, SortOrder.Ascending); 

     persons.ForEach(p => Console.WriteLine(p.ToString())); 

     persons.SortPeople(CompareOptions.BySalary, SortOrder.Descending); 

     persons.ForEach(p => Console.WriteLine(p.ToString())); 

     Console.ReadLine(); 
    } 
} 

public static class Extensions 
{ 
    public static void SortPeople(this List<Person> lst, CompareOptions opt1,SortOrder ord){ 
     lst.Sort((Person p1, Person p2) => 
      { 
       switch (opt1) 
       { 
        case CompareOptions.ByFirstName: 
         return ord == SortOrder.Ascending ? p1.FirstName.CompareTo(p2.FirstName) : p2.FirstName.CompareTo(p1.FirstName); 
        case CompareOptions.ByLastName: 
         return ord == SortOrder.Ascending ? p1.LastName.CompareTo(p2.LastName) : p2.LastName.CompareTo(p1.LastName); 
        case CompareOptions.BySalary: 
         return ord == SortOrder.Ascending ? p1.Salary.CompareTo(p2.Salary) : p2.Salary.CompareTo(p1.Salary); 
        default: 
         return 0; 
       } 
      }); 
    } 
} 

public class Person 
{ 
    public double Salary { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 

    public Person(string first, string last, double salary) 
    { 
     this.Salary = salary; 
     this.FirstName = first; 
     this.LastName = last; 
    } 

    public override string ToString() 
    { 
     return string.Format("{0} {1} has a salary of {2}", this.FirstName, this.LastName, this.Salary); 
    } 
} 

public enum CompareOptions { ByFirstName, ByLastName, BySalary } 
public enum SortOrder { Ascending, Descending } 

}

6

तुम सच में enums की ज़रूरत है? मुझे नहीं लगता कि यह है कि एक विधि में अपनी खोज तर्क encapsulating अधिक स्पष्ट या सिर्फ LINQ तरीकों का उपयोग कर अधिक से अधिक सूखी है:

persons.OrderBy(p => p.FirstName); 
persons.OrderByDescending(p => p.Salary); 

आदि

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