2009-05-05 23 views
3

Nehmen Sie das folgende BeispielDie Summe einer bestimmten Eigenschaft aller Elemente in einer Liste

Ich habe eine Klasse

public class SomeItem 
{ 
    public string Name; 
    public DateTime Published; 
    public uint16 Size; 
} 

Ich habe ein List<SomeItem> und ich möchte die Gesamtgröße aller berechnen Artikel.
In C# würde ich einfach

var totalSize = items.Sum((i) => i.Size); 

Ich habe einen Blick auf die Liste Funktionen in F # genommen schreiben, aber sie immer über die Typen beschweren.

Wie würden Sie das in F # schreiben?

(Ich habe die Suchmaschinen versucht, aber für F # Suchmaschinen-Unterstützung ist schrecklich)

Antwort

8

Angenommen, Sie einen Wert vom Typ haben IEnumerable<Item>, Sie sum_by vom Seq Modul verwenden können:

let totalSize = items |> Seq.sum_by (fun (i : Item) -> i.Size) 

Beachten Sie, dass F # 's Microsoft.FSharp.Collections.List<T> Typ nicht die gleiche Klasse wie das ist, das Sie von System.Collections.Generic.List<T> verwendet werden könnten, und sie sind nicht austauschbar. Die Methoden im Seq-Modul funktionieren jedoch unter jeder IEnumerable<T>, und IEnumerable<T> ist die gleiche zwischen F # und C#.

+0

Sie haben so ziemlich wörtlich geschrieben, was ich geschrieben habe. Es gibt zu viele Ninja Poster auf dieser Seite. ;) – gradbot

+0

Heh, ich bin mir nicht sicher, ob ich mich als Ninja zähle;). Nicht sicher, warum diese Antwort abgelehnt wurde. –

+0

Ich sehe nicht, warum du auch runtergerannt wurdest. Danke für die Antwort – TimothyP

1

Dies ist in F # und anderen funktionalen Sprachen „Falten“. Suchen Sie nach Beispielen von Seq.fold.

+0

Die anderen vorgeschlagen Seq.sum_by, Ich bin interessiert, warum Sie Seq.fold vorschlagen – TimothyP

+0

@TimothyP: Seq.fold würde die Arbeit tun, nur dass es Zweck ist allgemeiner als sum_by (es könnte mehrere alle Werte in eine Liste zusammen, zum Beispiel). sum_by ist die schöne einfache Lösung in diesem Fall. – Noldorin

+0

Einverstanden. Wenn Sie jedoch nach Suchbegriffen suchen, die "Dinge für alle Elemente in einer Sequenz erledigen und ein einziges Ergebnis liefern", dann bietet die Suche nach Falten/Falten die allgemeine Lösung. –

2
let totalSize = items |> List.sum_by (fun i -> i.Size) 

LINQ arbeitet in F # zu fein, aber es ist wahrscheinlich am beste Liste Verständnis wie oben zu verwenden, da es in der funktionalen Tradition mehr ist (und führt auch etwas schneller, weil es nicht IEnumerable<T> nicht verwendet).

+1

Dies setzt voraus, dass Sie übrigens eine F # 'List 'verwenden (dh eine verkettete Liste) und nicht die in System.Collections.Generic, die Sie * in F * im Allgemeinen nicht verwenden (obwohl F # auch einen Alias ​​für Es heißt 'ResizeArray'. – Noldorin

+0

Nun, die Liste kommt aus einer C# -Bibliothek, also ist es die System.Collections.Generic Liste, aber Sie haben mich gehen, thnx – TimothyP

+0

Da ich dies auf einer 'normalen' Liste mache, habe ich die Seq.sum_by – TimothyP

Verwandte Themen