Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delete duplicate rows from two dimentsional array

Let's say I have two dimensional array that represents simple matrix

int[,] matrix= new int[,] { { 1, 2 }, { 3, 4 }, { 1, 2 }, { 7, 8 } };

It looks like that

1 2
3 4
1 2
7 8

Is there any way to delete duplicate rows using LINQ and make array to look like this?

1 2
3 4
7 8
like image 504
Mitya Avatar asked Oct 25 '13 10:10

Mitya


1 Answers

This is not really Linq, but you can define some helper method as if they were Linq methods.

The simpler algorithm should be:

  1. Convert to a list of list
  2. Apply a distinct with a custom comparer
  3. Rebuild another array

This looks like this:

public static class MyExtensions
{
    public static IEnumerable<List<T>> ToEnumerableOfEnumerable<T>(this T[,] array)
    {
        int rowCount = array.GetLength(0);
        int columnCount = array.GetLength(1);

        for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
        {
            var row = new List<T>();
            for (int columnIndex = 0; columnIndex < columnCount; columnIndex++)
            {
                row.Add(array[rowIndex, columnIndex]);
            }
            yield return row;
        }
    }
    public static T[,] ToTwoDimensionalArray<T>(this List<List<T>> tuples)
    {
        var list = tuples.ToList();
        T[,] array = null;
        for (int rowIndex = 0; rowIndex < list.Count; rowIndex++)
        {
            var row = list[rowIndex];
            if (array == null)
            {
                array = new T[list.Count, row.Count];
            }
            for (int columnIndex = 0; columnIndex < row.Count; columnIndex++)
            {
                array[rowIndex, columnIndex] = row[columnIndex];
            }
        }
        return array;
    }
}

The custom List comparer (copied from a Jon Skeet's answer):

public class ListEqualityComparer<T> : IEqualityComparer<List<T>>
{
    public bool Equals(List<T> x, List<T> y)
    {
        return x.SequenceEqual(y);
    }

    public int GetHashCode(List<T> obj)
    {
        int hash = 19;
        foreach (var o in obj)
        {
            hash = hash * 31 + o.GetHashCode();
        }
        return hash;
    }
}

The usage :

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        var array = new[,] { { 1, 2 }, { 3, 4 }, { 1, 2 }, { 7, 8 } };
        array = array.ToEnumerableOfEnumerable()
                     .Distinct(new ListEqualityComparer<int>())
                     .ToList()
                     .ToTwoDimensionalArray();
    }
}
like image 155
Cyril Gandon Avatar answered Nov 02 '22 23:11

Cyril Gandon