wake-up-neo.com

Wählen Sie in Linq mehrere Felder aus der Liste aus

In ASP.NET C # habe ich eine Struktur:

public struct Data
{
    public int item1;
    public int item2;
    public int category_id;
    public string category_name;
}

und ich habe eine Liste davon. Ich möchte category_id und category_name auswählen, eine DISTINCT und schließlich eine ORDERBY auf category_name ausführen.

Folgendes habe ich jetzt:

List<Data> listObject = getData();
string[] catNames = listObject
                    .Select(i=> i.category_name)
                    .Distinct()
                    .OrderByDescending(s => s)
                    .ToArray();

Dies erhält offensichtlich nur den Kategorienamen. Meine Frage ist, wie bekomme ich mehrere Felder und in welcher Datenstruktur werde ich dies speichern (nicht in string[])?

BEARBEITEN

Die Verwendung einer Liste von Strukturen ist nicht in Stein gemeißelt. Wenn es ratsam wäre, meine Backing-Datenstruktur zu ändern, um die Auswahl zu erleichtern (ich schreibe viele davon), würde ich gerne Empfehlungen geben.

112
Chet

Mit anonymen Typen können Sie beliebige Felder in Datenstrukturen auswählen, die später in Ihrem Code stark typisiert werden:

var cats = listObject
    .Select(i => new { i.category_id, i.category_name })
    .Distinct()
    .OrderByDescending(i => i.category_name)
    .ToArray();

Da Sie es (scheinbar) für eine spätere Verwendung speichern müssen, können Sie den GroupBy-Operator verwenden:

Data[] cats = listObject
    .GroupBy(i => new { i.category_id, i.category_name })
    .OrderByDescending(g => g.Key.category_name)
    .Select(g => g.First())
    .ToArray();
200
Jason
var selectedCategories =
    from value in
        (from data in listObject
        orderby data.category_name descending
        select new { ID = data.category_id, Name = data.category_name })
    group value by value.Name into g
    select g.First();

foreach (var category in selectedCategories) Console.WriteLine(category);

Edit : Es wurde mehr LINQ-ey!

23
IRBMe

Sie können einen anonymen Typ verwenden:

.Select(i => new { i.name, i.category_name })

Der Compiler generiert den Code für eine Klasse mit den Eigenschaften name und category_name und gibt Instanzen dieser Klasse zurück. Sie können Eigenschaftsnamen auch manuell angeben:

i => new { Id = i.category_id, Name = i.category_name }

Sie können eine beliebige Anzahl von Eigenschaften haben.

22
Mehrdad Afshari

Dies ist eine Aufgabe, für die anonyme Typen sehr gut geeignet sind. Sie können Objekte eines Typs zurückgeben, der automatisch vom Compiler erstellt und aus der Verwendung abgeleitet wird.

Die Syntax hat folgende Form:

new { Property1 = value1, Property2 = value2, ... }

Versuchen Sie in Ihrem Fall etwa Folgendes:

var listObject = getData();
var catNames = listObject.Select(i =>
    new { CatName = i.category_name, Item1 = i.item1, Item2 = i.item2 })
    .Distinct().OrderByDescending(s => s).ToArray();
5
Noldorin
var result = listObject.Select( i => new{ i.category_name, i.category_id } )

Hierbei werden anonyme Typen verwendet, daher müssen Sie das Schlüsselwort var verwenden, da der resultierende Typ des Ausdrucks nicht im Voraus bekannt ist.

4
Paul van Brenk

Sie können es zu einem KeyValuePair machen, also einen "IEnumerable<KeyValuePair<string, string>>" zurückgeben.

Also wird es so sein:

.Select(i => new KeyValuePair<string, string>(i.category_id, i.category_name )).Distinct();
3
Victor
(from i in list
 select new { i.category_id, i.category_name })
 .Distinct()
 .OrderBy(i => i.category_name);
3
Joe Chung

Sie können mit linq Select mehrere Felder auswählen, wie oben in verschiedenen Beispielen gezeigt, die als anonymer Typ zurückgegeben werden. Wenn Sie diesen anonymen Typ vermeiden möchten, ist der einfache Trick hier.

var items = listObject.Select(f => new List<int>() { f.Item1, f.Item2 }).SelectMany(item => item).Distinct();

Ich denke, das löst dein Problem

2
AR M
public class Student
{
    public string Name { set; get; }
    public int ID { set; get; }
}

class Program
{
  static void Main(string[] args)
    {
        Student[] students =
        {
        new Student { Name="zoyeb" , ID=1},
        new Student { Name="Siddiq" , ID=2},
        new Student { Name="sam" , ID=3},
        new Student { Name="james" , ID=4},
        new Student { Name="sonia" , ID=5}
        };

        var studentCollection = from s in students select new { s.ID , s.Name};

        foreach (var student in studentCollection)
        {
            Console.WriteLine(student.Name);
            Console.WriteLine(student.ID);
        }
    }
}
0
Zoyeb Shaikh