Reputation: 20464
I Have a List(Of Integer())
where the integer arrays contains sorted elements but the elements of the list aren't sorted, example:
MyList(0) = {1, 35, 39, 42}
MyList(1) = {1, 5, 9, 12}
MyList(2) = {6, 8, 19, 62}
How I could sort the list index basing me in the order of the Arrays to produce this?:
MyList(0) = {1, 5, 9, 12}
MyList(2) = {1, 35, 39, 42}
MyList(1) = {6, 8, 19, 62}
I was trying to evaluate only the first element of each Array but of course this not produce the desired result 'cause is not evaluating the rest values:
MyList = (From arr As Integer() In MyList Order By arr.First Ascending).ToList
Upvotes: 0
Views: 116
Reputation: 6122
Have a look at merge sort. https://en.wikipedia.org/wiki/Merge_sort has the details
Upvotes: 1
Reputation: 9991
As a supplement to LB's answer, one can create a more generic array comparer like this:
Public Class ArrayComparer(Of T As IComparable)
Implements IComparer(Of T())
Public Function Compare(x() As T, y() As T) As Integer Implements IComparer(Of T()).Compare
Dim i, n As Integer
For i = 0 To (Math.Min(x.Count, y.Count) - 1)
n = x(i).CompareTo(y(i))
If (n <> 0) Then Return n
Next
Return x.Length.CompareTo(y.Length)
End Function
End Class
Now, given the following list:
Dim list As New List(Of Integer())
For i As Integer = 1 To 2
For j As Integer = 1 To 2
For k As Integer = 1 To 2
For l As Integer = 1 To 2
list.Add(New Integer() {i, j, k, l})
Next
list.Add(New Integer() {i, j, k})
Next
list.Add(New Integer() {i, j})
Next
list.Add(New Integer() {i})
Next
And the following action:
list = list.OrderBy((Function(a As Integer()) a), New ArrayComparer(Of Integer)).ToList()
The result looks like this:
1
1,1
1,1,1
1,1,1,1
1,1,1,2
1,1,2
1,1,2,1
1,1,2,2
1,2
1,2,1
1,2,1,1
1,2,1,2
1,2,2
1,2,2,1
1,2,2,2
2
2,1
2,1,1
2,1,1,1
2,1,1,2
2,1,2
2,1,2,1
2,1,2,2
2,2
2,2,1
2,2,1,1
2,2,1,2
2,2,2
2,2,2,1
2,2,2,2
If preferable, add a secondary sort expression to include the length.
list = list.OrderBy((Function(a As Integer()) a), New ArrayComparer(Of Integer)).ThenBy(Function(a As Integer()) a.Length).ToList()
Result:
1
2
1,1
1,2
2,1
2,2
1,1,1
1,1,2
1,2,1
1,2,2
2,1,1
2,1,2
2,2,1
2,2,2
1,1,1,1
1,1,1,2
1,1,2,1
1,1,2,2
1,2,1,1
1,2,1,2
1,2,2,1
1,2,2,2
2,1,1,1
2,1,1,2
2,1,2,1
2,1,2,2
2,2,1,1
2,2,1,2
2,2,2,1
2,2,2,2
Upvotes: 1
Reputation: 116138
If you want a c# answer
class ListComparer : IComparer<List<int>>
{
public int Compare(List<int> x, List<int> y)
{
for (int i = 0; i < Math.Min(x.Count, y.Count); i++)
{
if (x[i] != y[i]) return x[i] - y[i];
}
return x.Count - y.Count;
}
}
var newList = MyList.OrderBy(l => l, new ListComparer()).ToList();
EDIT: @ElektroStudios, this will be my first VB code:
I used the site you mentioned in comments , made a few changes and this is what I got
Dim MyList As New List(Of List(Of Integer))
MyList.Add(New List(Of Integer) From {1, 35, 39, 42})
MyList.Add(New List(Of Integer) From {1, 5, 9, 12})
MyList.Add(New List(Of Integer) From {6, 8, 19, 62})
Dim newList = MyList.OrderBy(Function(l) l, New ListComparer()).ToList()
Public Class ListComparer
Implements IComparer(Of List(Of Integer))
Public Function Compare1(x As List(Of Integer), y As List(Of Integer)) As Integer Implements IComparer(Of List(Of Integer)).Compare
For i As Integer = 0 To Math.Min(x.Count, y.Count) - 1
If x(i) <> y(i) Then
Return x(i) - y(i)
End If
Next
Return x.Count - y.Count
End Function
End Class
Upvotes: 3