2

Consider the code below

class Pin
{
   string Name; //can be either Numerical or AlphaNum
}

enum Place
{
    Left,
    Right
}

class Map
{
   Pin pin;
   Place Place;
   Rectangle Rect;
}

The Pin's Name field can be only numerical or alphanumerical, so I went by string to support both.

Now My quesion is if I have a List<Map> how can I sort this list by Pin's Name field? I tried the code below but it can't compile:

map.Sort((x, y) => x.Pin.Name.CompareTo(y.Pin.Name)); 
//Cannot implicitly convert type 'void' to 'System.Collections.Generic.List<DataModels.PinMap>
Dumbo
  • 13,555
  • 54
  • 184
  • 288
  • Take a look at http://stackoverflow.com/questions/3163922/sort-a-custom-class-list – Tomtom Aug 28 '12 at 11:35
  • 1
    What you have actually looks fine...? Are you sure your real code isn't `map = map.Sort(...);` ? – Marc Gravell Aug 28 '12 at 11:36
  • Sounds like you're trying to set map equal to the result of the call to Sort. Skip that (as sort will rearrange the elements in the list you're sorting) or use map = map.OrderBy(x => x.pin.Name).ToList(); – mlorbetske Aug 28 '12 at 11:41
  • @MarcGravell It seems taht I was doing a wrong assignement I mean returning the sort result in a method. But my question on sorting still is valid. – Dumbo Aug 28 '12 at 11:46
  • 1
    @Sean87 then sort it, then return-it; the `List.Sort` method is an in-place operation, so has no return value. i.e. `list.Sort(...); return list;` – Marc Gravell Aug 28 '12 at 11:52

3 Answers3

9

The code you showed doesn't produce that compiler error. I assume that you are trying to assign the result to a new variable or to itself. Something like this:

map = map.Sort(...);

That's not possible or necessary as List<T>.Sort is doing an in-place sort, i.e. it changes the original list and therefore doesn't return anything. So, simply removing the assignment should make the compiler error go away.

If you don't want an in-place sort, simply use Enumerable.OrderBy in combination with ToList to produce a new list:

var result = map.OrderBy(x => x.pin.Name).ToList();
Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
  • 1
    Sounds to me like the OP just needs to replace `map = map.Sort(...);` with `map.Sort(...);`... I'm just saying that "remove the `map = `" is probably more important to highlight than the LINQ alternative – Marc Gravell Aug 28 '12 at 11:39
  • @MarcGravell: Yes. That's what I just now thought, too. I was already changing my answer as you commented. Please check. – Daniel Hilgarth Aug 28 '12 at 11:41
  • I'd say it's good to have both, while it follows that `map = map.OrderBy(...).ToList()` has the same effect as `Sort()`, `Sort()` is faster. Conversely, `OrderBy(...)` beats `OrderBy(...).ToList()` but isn't always what one needs. Knowing about all three approaches is definitely a good thing. – Jon Hanna Aug 28 '12 at 11:44
1

LINQ to the rescue:

var ordered = map.OrderBy(x => x.pin.Name);

Assuming, of course, that none of the pins in the map is null. If it can be null, then:

var ordered = map.Where(x => x.pin != null).OrderBy(x => x.pin.Name);
Patryk Ćwiek
  • 14,078
  • 3
  • 55
  • 76
  • I disagree; this does not do what the question asks: it does not sort the list. – Marc Gravell Aug 28 '12 at 11:37
  • @MarcGravell in fairness, since it looks like the problem was with assigning the result of the sort, and since we don't see whether the assignment was back to the same list or not, it's not clear that this isn't precisely what they really want. – Jon Hanna Aug 28 '12 at 11:40
  • @Jon hmmmm... perhaps; indeed, the question could be clearer on this point. – Marc Gravell Aug 28 '12 at 11:41
0

Use Linq.

map = (from a in allAgents
      orderby a.AgentId
      select a).ToList<Map>();
MattW
  • 12,902
  • 5
  • 38
  • 65