Как суммировать значения в коллекции карт F # - PullRequest
2 голосов
/ 05 августа 2020

У меня есть Map<string,int>, где я хочу просуммировать все значения.

Он будет использоваться как словарь слов в игрушечном корректоре правописания, который описан здесь .

Наивная попытка

let wc myMap =
    Map.toSeq myMap
    |> Seq.sumBy (fun kvp -> (snd kvp))

ошибка FS0071 Рассмотрите возможность добавления дополнительных ограничений типа

Попытка 1

type MapFn = Map<string,int> -> int
let wc:MapFn = (function wm ->
                            Map.toSeq wm
                            |> Seq.sumBy (fun kvp -> (snd kvp)))

Попытка 2

type WordMap = WordMap of Map<string,int>
let wc (WordMap wm) = 
    Map.toSeq wm
    |> Seq.sumBy (fun kvp -> (snd kvp))

Обе попытки работают, но мне бы хотелось, чтобы код был аккуратнее. Как пример кода в Python sum(WORDS.values()).

WORDS = Counter(words(open('big.txt').read()))

def P(word, N=sum(WORDS.values())): 
    return WORDS[word] / N

Также интересно, является ли тип Map<string,int> лучшим выбором для моего словаря.

1 Ответ

2 голосов
/ 05 августа 2020

Элемент карты - это пара ключ / значение (KeyValuePair в вашем примере), а не кортеж. Таким образом, вы должны использовать kvp.Value вместо snd kvp, например:

myMap |> Seq.sumBy(fun item -> item.Value )

или используя Map.fold

myMap |> Map.fold (fun state key value -> state + value)  0
...