Reputation: 879
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.
Upvotes: 1
Views: 3774
Reputation: 366
an one line solution that i prefer for string!
//Sort by Name: list = List<string>() ...
list.Sort((x, y) => String.Compare(x, y, StringComparison.Ordinal));
Upvotes: 0
Reputation: 113442
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);
}
Upvotes: 0
Reputation: 10541
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());
}
}
Upvotes: 0
Reputation: 12025
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);
});
Upvotes: 2
Reputation: 838416
You might want to consider a natural sort.
Ordinary sort:
Natural sort:
You could read Natural Sorting in C#.
Upvotes: 1
Reputation: 6884
[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.
Upvotes: 0