2016-07-19 3 views
0

Ich bin auf ein Problem gestoßen und ich bin mir nicht sicher, ob ich etwas verpasse oder ob es in C# wirklich klobig ist.Mapping über ein 2D-Array

Ich habe ein 2D-Array (Foo[,]) und was ich tun möchte, ist es zu einer Bar[,], mit nur einem Func<Foo, Bar>. Grundsätzlich möchte ich eine Funktorinstanz für T[,] für jede gegebene T. Der "offensichtliche" Weg besteht natürlich darin, einfach ein neues Array von Grund auf aufzubauen, indem man über jede Spaltenzeile und -spalte iteriert und die Funktion manuell auf jede Zelle anwendet. Ich möchte wirklich nutzen LINQ für diese allerdings machen, weil es keinen Grund gibt, was auch immer dies komplizierter sein sollte als

from cell in matrix 
select f(cell) 

oder das Äquivalent matrix.Select(f).

Ich kann nicht anders, als zu denken, dass ich nicht der Erste sein kann, der das machen wollte, also frage ich mich, ob es etwas Ähnliches gibt, oder ist meine beste Wette, einfach meine eigenen LINQ-Erweiterungen zu schreiben 2D-Arrays?

Antwort

0

Es gibt keine LINQ-Methoden in .Net Framework, die direkt mit 2D-Array arbeiten. Das Beste, was Sie von integriertem Code erhalten - Iterieren über alle Einzelteile über nicht-generic IEnumerable mit manuellen Cast (Why do C# Multidimensional arrays not implement IEnumerable<T>?, Using Linq with 2D array, Select not found)

Als Lösung - eigene Erweiterungen schreiben oder Bibliothek.

+0

Das Schreiben einer Reihe von benutzerdefinierten LINQ-Erweiterungen scheint der einfachste und sauberste Pfad zu sein. Irgendwie mühsam, diese Art von Boilerplate-Code schreiben und pflegen zu müssen, aber naja. – kai

0

Nicht sicher, ob dies der "beste" Weg ist (was immer das bedeutet), aber das funktioniert zumindest. Kann leicht erweitert werden, wenn Sie mehr LINQ-Syntax benötigen.

Getestet mit dem folgenden (eher lüfterlosen) xunit-Fakt, fühlen Sie sich frei, auf Bugs hinzuweisen.

[Fact] 
public void MatrixSelect_GivenFunction_MapsMatrix() 
{ 
    var matrix = new[,] 
    { 
     {true, true}, 
     {false, true} 
    }; 

    var transformed = 
     from cell in matrix 
     select cell ? 1 : 0; 

    var expected = new[,] 
    { 
     {1, 1}, 
     {0, 1} 
    }; 
    Assert.Equal(expected, transformed); 
}