2012-03-09 20 views
9

Mam dwa lista jakC#: Jak posortować listę obiektów w oparciu o listy ciąg

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" }, 
          }; 

Gdzie Test jest klasa jak

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

muszę uporządkować elementy w l_lstStudents na podstawie l_lstNames. Tak uporządkowany wykaz będzie jak,

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" }, 
         }; 

Teraz używam for to zrobić.

Jak

  1. Utwórz nową listę Test obiektów.

  2. Powtórz pętlę dla l_lstNames i pobierz obiekt Test z l_lstStudent i dodaj to samo do nowo utworzonej listy. Wreszcie przypisać nową listę l_lstStudent

Proszę mi pomóc to zrobić w prosty sposób (Linq lub lambda)

+0

Wiem, mówiłeś proste, ale jesteś bardziej związane z wykonaniem lub kilku liniach kodu? – Tung

+0

możliwy duplikat [Listy sortowania C# na podstawie innej listy] (http://stackoverflow.com/questions/3355928/c-sharp-sort-list-based-on-another-list) – nawfal

Odpowiedz

9

Spróbuj tego:

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

Myślę, że wyraża wolę całkiem Wyraźnie.

1

Spróbuj czegoś takiego:

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

Jak o

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

Korzystanie

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

w małym programem testowym

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(); 
    } 
} 

skutkuje

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 

a więc jest:

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

Spróbuj tego. Wprowadzenie go w słowniku może zaoszczędzić trochę patrzeć w górę czas:

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

wypróbować z następującego kodu:

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(); 
Powiązane problemy