简体   繁体   中英

Sort 2D array in C#

I was trying to compare a 2D array in C# using IComparer but not able to compile the code from my point of view in sort method ab is assumed to be a jagad array instead of a normal array .Does any one know how to solve that

int[,] ab = new int[3, 4] 
{ 
    { 1, 2, 3, 4 }, 
    { 5, 6, 7, 8 }, 
    { 2, 3, 4, 5 } 
}; 
Array.Sort<int[]>(ab, new ComparerTwoDArray()); 
foreach (var i in ab) 
{ 
    Console.WriteLine(i); 
} 

class ComparerTwoDArray : IComparer<int[]> 
{ 
    int ix; 

    public int Compare(int[] x, int[] y) 
    { 
        return x[0].CompareTo(y[0]); 
    } 
}

You are not using the proper method: https://msdn.microsoft.com/en-us/library/system.array.sort%28v=vs.110%29.aspx

Array.Sort Method: Sorts the elements in a one-dimensional array.

You could use List<List<int>> and then use its Sort LINQ extension, like:

list.Sort((x,y) => x[0].CompareTo(y[0]));

Unfortunately a multi-dimensional array is a quite static beast. You can easily access single elements within it by providing the n-dimensional coordinates (eg. array[2,8,4] in a 3d array), but you can't access any whole areas (like rows, columns, rectangles, etc.).

If you really have the need to do such a kind of re-sorting you shouldn't save your data within a multi-dimensional array. Instead put it into a jagged array or a list of lists or even a IReadOnlyDictionary<int, IReadOnlyDictionary<int, IReadOnlyDictionary<int, int>>> for a 4 dimensions sparse matrix. In that case you could quite easily write a comparer for each dimension as you like.

In your case you just need a something like List<IReadOnlyList<int>> and a IComparer<IReadOnlyList<T>> which could possibly be implemented like this:

public class ListComparer<T> : IComparer<IReadOnlyList<T>>
{
    public static readonly IComparer<IReadOnlyList<T>> Default = new ListComparer<T>();

    private readonly bool _checkCount;
    private readonly int _numberOfElementsToCompare;
    private readonly IComparer<T> _elementComparer;

    public ListComparer()
        : this(true, 1, Comparer<T>.Default)
    {
    }

    public ListComparer(
        bool checkCount,
        int numberOfElementsToCompare,
        IComparer<T> elementComparer)
    {
        _checkCount = checkCount;
        _numberOfElementsToCompare = numberOfElementsToCompare;
        _elementComparer = elementComparer
            ?? throw new ArgumentNullException(nameof(elementComparer));
    }

    public int Compare(IReadOnlyList<T> x, IReadOnlyList<T> y)
    {
        if (ReferenceEquals(x, y))
            return 0;

        if (ReferenceEquals(x, null))
            return -1;

        if (ReferenceEquals(y, null))
            return 1;

        if (_checkCount)
        {
            var diff = x.Count.CompareTo(y.Count);

            if (diff != 0)
                return diff;
        }

        return x.Take(_numberOfElementsToCompare)
            .Zip(y, (i, j) => _elementComparer.Compare(i, j))
            .SkipWhile(value => value == 0)
            .FirstOrDefault();
    }
}

And would be used:

    var matrix = new List<IReadOnlyList<int>>
    {
        { new List<int> { 1, 2, 3, 4 }  },
        { new List<int> { 5, 6, 7, 8 }  },
        { new List<int> { 2, 3, 4, 5 }  }
    };

    matrix.Sort(ListComparer<int>.Default);

    foreach (var item in matrix)
    {
        Console.WriteLine(String.Join(", ", item));
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM