ElektroStudios
ElektroStudios

Reputation: 20464

How to sort a List of Arrays that contains sorted Arrays?

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

Answers (3)

Yuvika
Yuvika

Reputation: 6122

Have a look at merge sort. https://en.wikipedia.org/wiki/Merge_sort has the details

Upvotes: 1

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

L.B
L.B

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

Related Questions