tags:

views:

2076

answers:

6

In ASP.NET C# I have a struct:

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

and I have a List of those. I want to select category_id and category_name, running a DISTINCT and finally an ORDERBY on category_name.

Here's what I have now:

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

This obviously just gets the category name. My question is, how do I get multiple fields, and what data structure will I store this in (not a string[])?

EDIT

Using a list of structs is not set in stone. If it would be advisable to change my backing data structure to make selects easier (I'll be writing a lot of these) then I'd gladly take recommendations.

+2  A: 

You could use an anonymous type:

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

The compiler will generate the code for a class with name and category_name properties and returns instances of that class. You can also manually specify property names:

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

You can have arbitrary number of properties.

Mehrdad Afshari
+1  A: 
var result = listObject.Select( i => new{ i.category_name, i.category_id } )

This uses anonymous types so you must the var keyword, since the resulting type of the expression is not known in advance.

pb
+1  A: 

This is task for which anonymous types are very well suited. You can return objects of a type that is created automatically by the compiler, inferred from usage.

The syntax is of this form:

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

For your case, try something like the following:

var listObject = getData();
var catNames = listObject.Select(i =>
    new { CatName = i.category_name, Item1 = i.item1, Item2 = i.item2 })
    .Distinct().OrderByDescending(s => s).ToArray();
Noldorin
+2  A: 

Anonymous types allow you to select arbitrary fields into data structures that are strongly typed later on in your code:

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

Since you (apparently) need to store it for later use, you could use the GroupBy operator:

Data[] cats = listObject
    .GroupBy(i => new { i.category_id, i.category_name })
    .OrderByDescending(g => g.Key.category_name)
    .Select(g => g.First())
    .ToArray();
Jason
+1  A: 
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: Made it more LINQ-ey!

IRBMe
Beaten like a red headed step child.
IRBMe
Haha, thanks, well, I do appreciate the help. Apparently this wasn't the most difficult question in the world.
Chet
A: 
(from i in list
 select new { i.category_id, i.category_name })
 .Distinct()
 .OrderBy(i => i.category_name);
Joe Chung