2016-06-30 6 views
4

I diese Funktion haben verschiedene Elemente einer Anordnung zurückzukehren:finden verschiedene Paare eines 2D-Arrays

public static object[] Distinct(object[] array) 
{ 
    return array.Select(x => x.ToString()).Distinct().ToArray(); 
} 

Ich mag würde dies mit 2 Spalten zu einer Matrix erweitern, und es sollte verschiedene Paare zurückzukehren.

funktioniert das natürlich nicht:

public static object[,] Distinct(object[,] array) 
{ 
    return array.Select((x,y) => x.ToString(), y.ToString()).Distinct().ToArray(); 
} 

Aber ich denke, es ist schön, was zeigt, zu tun, ich versuche. Alle Hinweise wären toll.

+1

Warum nicht zurück 'string []' und 'string [,]' statt 'Objekt []' und 'Objekt [,]'? Das würde deutlich machen, dass Sie die übergebenen Originalobjekte nicht zurückgeben. – juharr

Antwort

3

Sie könnten das 2D-Array in eine Sequenz von Tuple umsetzen und dann Distinct darauf ausführen. Dann übersetze es zurück in ein 2D-Array.

public static object[,] Distinct(object[,] array) 
{ 
    var distinct = Enumerable.Range(0, array.GetLength(0)) 
     .Select(i => Tuple.Create(array[i, 0].ToString(), array[i, 1].ToString())) 
     .Distinct() 
     .ToList(); 
    var newArray = new object[distinct.Count, 2]; 
    for (int i = 0; i < distinct.Count; i++) 
    { 
     newArray[i, 0] = distinct[i].Item1; 
     newArray[i, 1] = distinct[i].Item2; 
    } 

    return newArray; 
} 

Beachte, dass dies unter der Annahme, dass die Länge der zweiten Dimension des Arrays> = 2 ist, und wenn er größer ist, dann ist es nur die Werte aus den ersten 2 Positionen zurückzukehren.

1

Schließlich würden Sie es als Erweiterungsmethode mit generischen tun?

public static T[,] Distinct<T>(this T[,] array) 
{ 
    var result = Enumerable.Range(0, array.GetLength(0)) 
     .Select(i => new { x = array[i, 0], y = array[i, 1] }) 
     .Distinct(); 

    T[,] ret = new T[result.Count(), 2]; 
    for (int i = 0; i < result.Count(); i++) 
    { 
     ret[i, 0] = result.ElementAt(i).x; 
     ret[i, 1] = result.ElementAt(i).y; 
    } 

    return ret; 
} 

So wäre dies möglich sein:

int[,] test = new int[,] { { 1, 2 }, { 1, 3 }, { 2, 4 }, { 1, 3 } }; 
var result = test.Distinct(); 
+0

Besser, ToList' für das Ergebnis zu verwenden, damit Sie die Sequenz für den Aufruf von 'Count' und jeden Aufruf von' ElementAt nicht iterieren müssen '. – juharr

+1

Möchte auch eine Version betrachten, die in einem 'IEqualityComparer ' übergeben wird, das an 'Distinct' übergeben wird, wenn Sie steuern möchten, wie es die Elemente im Array vergleicht. – juharr

+0

@juharr sehr gute Idee –