2009-05-05 3 views
3

следующий пример,Сумма определенного свойства всех элементов в списке

У меня есть класс

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

У меня есть List<SomeItem>, и я хочу, чтобы вычислить общий размер всех Предметы.
В C# я бы просто написать

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

Я принял взглянуть на функции списка в F #, но они всегда жалуются на типы.

Как вы напишете это в F #?

(я пробовал поисковые системы, но поддержка поисковой системы для F # ужасна)

ответ

8

Если у вас есть значение типа IEnumerable<Item>, вы можете использовать sum_by из Seq модуля:

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

Заметим, что F # s Microsoft.FSharp.Collections.List<T> тип не тот же класс, как тот, который вы могли бы быть использованы для из System.Collections.Generic.List<T>, и они не связаны друг с другом. Однако методы в модуле Seq работают с любыми IEnumerable<T> и IEnumerable<T> совпадают между F # и C#.

+0

Вы просто много писали, что я пишу. На этом сайте слишком много плакатов ниндзя. ;) – gradbot

+0

Хе, не уверен, что я считаю себя ниндзя;). Не уверен, почему этот ответ пришел, - проголосовали. –

+0

Я не понимаю, почему вы тоже заняли ничто. Спасибо за ответ – TimothyP

1

Это «складные» в F # и других функциональных языках. Ищите примеры Seq.fold.

+0

Другие предложения Seq.sum_by, Меня интересует, почему вы предлагаете Seq.fold – TimothyP

+0

@TimothyP: Seq.fold выполнит эту работу, просто это назначение более общее, чем sum_by (оно может содержать несколько значений в например, список). sum_by - приятное простое решение в этом случае. – Noldorin

+0

Согласовано. Однако, если вы ищете поисковые термины, которые описывают «делать вещи для всех элементов в последовательности и придумывают один результат», тогда поиск складчатости/складывания даст вам общее решение. –

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

LINQ прекрасно работает в F # тоже, но это, вероятно, лучше всего использовать список понимание, как выше, так как это больше в функциональной традиции (а также выполняет несколько быстрее, потому что он не использует IEnumerable<T>).

+1

Предполагается, что вы используете F # 'List', кстати (т. Е. Связанный список), а не тот, что находится в System.Collections.Generic, который вы * обычно * избегаете в F # (хотя F # также имеет псевдоним для он называется 'ResizeArray'). – Noldorin

+0

Ну, список исходит из библиотеки C#, поэтому это список System.Collections.Generic, но вы меня заставили, thnx – TimothyP

+0

Так как я делаю это в «нормальном» списке, я использовал Seq.sum_by – TimothyP