views:

80

answers:

5

Hello, how could i sort objects in list by their name? Example:

mapPart_1_0
mapPart_1_2
mapPart_1_4
mapPart_1_6
mapPart_1_8
mapPart_1_10
mapPart_1_12
mapPart_1_24
mapPart_2_1
mapPart_2_11
Big list continues... (somewhere in that list are missing that aper in sorted one)

Into:

mapPart_1_0
mapPart_1_1
mapPart_1_2
mapPart_1_3
mapPart_1_4
mapPart_1_5
...
mapPart_2_1
mapPart_2_2
mapPart_2_3
...
mapPart_2_11
...

Or could i change object name to something else so it would be easier to short?

Thank you.

A: 

[Check][1] this question

what you need is a Sort function with a custom IComparer. What you have now is the default icomparer when you use sort. this will check on a field value.

When you create a custom IComparer (you do this in you class by implementing the Icomparable interface). what it does is: your object checks itself to every other object in the list you sort.

this is done by a function. (don't worry VS will implementd it when refering your interface

public class  ThisObjectCLass : IComparable{

    public int CompareTo(object obj) {
            ThisObjectCLass something = obj as ThisObjectCLass ;
            if (something!= null) 
                if(this.key.Split("_")[1].CompareTo(object.key.Split("_")[1]) == 0){
                // extratc the numbers from your name and compare the numbers, you have            to add some logic but I assume you know something about c#
                //then:
                   if .....
                }
                else if(this.key.Split("_")[1] "is more important then(use some logic here)" object.key.Split("_")[1]){
                 return 1
                }
                else return -1
            else
               throw new ArgumentException("I am a dumb little rabid, trying to compare different base classes");
        }
}

read on the links above for better information.

Nealv
A: 

This involves some liberal assumptions about your requirements, and is a quick hack, but...

var groups = myList.Select (text => 
new
 { 
  FirstNum = int.Parse(text.Split('_')[1]), 
  SecondNum = int.Parse(text.Split('_')[2])
 })
.GroupBy(a => a.FirstNum, a => a.SecondNum);


foreach(var group in groups.OrderBy(g => g.Key))
{
  int min = group.Min();
  int max = group.Max();

  for(int i=min; i<=max; i++)
    yield return string.Format ("mapPart_{0}_{1}", group.key, i);

}
Ani
Thank you! This helped me allot.
Semas
No problem. There are certainly people around who could supply better responses, if only if you could be clearer about the problem statement.
Ani
+1  A: 

You might want to consider a natural sort.

Ordinary sort:

  • mapPart_1_1
  • mapPart_1_10
  • mapPart_1_2

Natural sort:

  • mapPart_1_1
  • mapPart_1_2
  • mapPart_1_10

You could read Natural Sorting in C#.

Mark Byers
+1  A: 

I think you could do something like this (not tested)

var yourList= new List<YourObject>();
//add items to your list

yourList.Sort(delegate(YourObject p1, YourObject p2)
              {
                  //you can make this delegate more complex if you need it
                  return p1.Name.CompareTo(p2.Name);
              });
Jonathan
A: 

Looks like this might be what you wanted, assuming you want the sorting to obey each token? To be honest I'm not sure what you want your results to be...

class Program
{
    public class ObjectNameComparer : IComparer<object>
    {
        public int Compare(object x, object y)
        {
            var n1 = x.ToString().Split('_');
            var n2 = y.ToString().Split('_');
            var nameCompare = string.Compare(n1[0], n2[0], StringComparison.OrdinalIgnoreCase);
            if (nameCompare == 0)
            {
                var i1 = int.Parse(n1[1]);
                var i2 = int.Parse(n2[1]);
                if (i1 == i2)
                {
                    var i12 = int.Parse(n1[2]);
                    var i22 = int.Parse(n2[2]);
                    return i12 - i22;
                }
                return i1 - i2;
            }
            return nameCompare;
        }
    }

    static void Main(string[] args)
    {
        var objectList = new List<object>();

        objectList.AddRange(new object[]
            {
                "mapPart_1_0",
                "mapPart_1_10",
                "mapPart_100_10",
                "mapPart_1_12",
                "mapPart_22_11",
                "mapPart_1_24",
                "mapPart_2_1",
                "mapPart_10_24",
                "mapPart_2_11",
            });

        var ordered = objectList.OrderBy(a => a, new ObjectNameComparer());

    }
}
Codesleuth