2012-03-09 28 views
9

列表上對象的列表兩個列表像C#:如何排序基於我有串

List<String> l_lstNames = new List<String> { "A1", "A3", "A2", "A4", "A0" }; 

List<Test> l_lstStudents = new List<Test> 
          { new Test { Age = 20, Name = "A0" }, 
           new Test { Age = 21, Name = "A1" }, 
           new Test { Age = 22, Name = "A2" }, 
           new Test { Age = 23, Name = "A3" }, 
           new Test { Age = 24, Name = "A4" }, 
          }; 

哪裏Test是類像

public class Test 
    { 
     public String Name; 
     public Int32 Age; 
    } 

我需要對項目進行排序在l_lstStudents的基礎上l_lstNames。因此,排序列表就會像,

List<Test> l_lstStudents = new List<Test> 
         { new Test { Age = 21, Name = "A1" }, 
          new Test { Age = 23, Name = "A3" }, 
          new Test { Age = 22, Name = "A2" }, 
          new Test { Age = 24, Name = "A4" }, 
          new Test { Age = 20, Name = "A0" }, 
         }; 

現在,我使用for做到這一點。

  1. 創建Test對象的新名單。

  2. 迭代l_lstNames的循環並從l_lstStudent中獲取Test對象,並將其添加到新創建的列表中。最後,新的列表分配給l_lstStudent

請幫我做一個簡單的方法(LINQ或λ)

+0

我知道你說的簡單,但你更關心的是性能或幾行的代碼? – Tung 2012-03-09 11:45:00

+0

[C#排序列表基於另一個列表]的可能重複(http://stackoverflow.com/questions/3355928/c-sharp-sort-list-based-on-another-list) – nawfal 2013-10-15 15:07:49

回答

9

試試這個:

l_lstStudents = l_lstStudents.OrderBy(s => l_lstNames.IndexOf(s.Name)).ToList() 

我覺得挺表達意向清晰。

1

試着這麼做:

List<String> l_lstNames = new List<String> { "A1", "A3", "A2", "A4", "A0" }; 

List<Test> l_lstStudents = new List<Test> 
          { new Test { Age = 20, Name = "A0" }, 
           new Test { Age = 21, Name = "A1" }, 
           new Test { Age = 22, Name = "A2" }, 
           new Test { Age = 23, Name = "A3" }, 
           new Test { Age = 24, Name = "A4" }, 
          }; 

// We transform the list in a dictionary to make it faster to access. 
// The first Select creates a new object with the index of the name and 
// the ToDictionary creates the Dictionary. 
// Note that technically on a small list (like 5 elements) 
// it's probably faster to IndexOf directly the List... 
// This is the problem of premature optimization :-) :-) 
// If you know the list will always be 5 elements then probably 
// IndexOf is more than enough. 
var dict = l_lstNames.Select((p, i) => new { Index = i, Name = p }) 
        .ToDictionary(p => p.Name, p => p.Index); 

// We sort it. This works because 3 < 5 => 3 - 5 < 0, 5 > 3 => 5 - 3 > 0, 5 == 5 => 5 - 5 == 0 
l_lstStudents.Sort((p, q) => dict[p.Name] - dict[q.Name]); 

// We could do something like and it would be clearer. 
l_lstStudents.Sort((p, q) => dict[p.Name].CompareTo(dict[q.Name])); 
2

如何

var studentLookup = l_lstStudents.ToDictionary(s => s.Name, s => s); 
return l_lstNames.Select(n => studentLookup[n]); 
1

在一個小的測試程序中使用

l_lstStudents = l_lstStudents.OrderBy(x => l_lstNames.IndexOf(x.Name)).ToList(); 

public class Test 
{ 
    public String Name; 
    public Int32 Age; 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     List<String> l_lstNames = new List<String> { "A1", "A3", "A2", "A4", "A0" }; 

     List<Test> l_lstStudents = new List<Test> 
            { new Test { Age = 20, Name = "A0" }, 
             new Test { Age = 21, Name = "A1" }, 
             new Test { Age = 22, Name = "A2" }, 
             new Test { Age = 23, Name = "A3" }, 
             new Test { Age = 24, Name = "A4" }, 
            }; 

     l_lstStudents = l_lstStudents.OrderBy(x => l_lstNames.IndexOf(x.Name)).ToList(); 
    } 
} 

結果

Age  21  int 
Name "A1" string 

Age  23  int 
Name "A3" string 

Age  22  int 
Name "A2" string 

Age  24  int 
Name "A4" string 

Age  20  int 
Name "A0" string 

,因此是:

List<Test> l_lstStudents = new List<Test> 
         { new Test { Age = 21, Name = "A1" }, 
          new Test { Age = 23, Name = "A3" }, 
          new Test { Age = 22, Name = "A2" }, 
          new Test { Age = 24, Name = "A4" }, 
          new Test { Age = 20, Name = "A0" }, 
         }; 
1

試試這個。把它在字典中可以節省一些查詢時間:

int i = 0; 
Dictionary<string, int> ordinalValues = l_lstNames.ToDictionary(name => name, name => i++); 
var sortedStudents = l_lstStudents.OrderBy(a => ordinalValues[a.Name]).ToList(); 
1

試試用下面的代碼:

l_lstStudents = (from name in l_lstNames 
        join student in l_lstStudents 
        on name equals student.Name 
        select student).ToList<Test>(); 
1
var newList = l_lstNames.Join(l_lstStudents, 
    s => s, 
    test => test.Name, 
    (s, test) => new Test { Name = s, Age = test.Age } 
    ).ToList();