FSharpList <string>в IList <string>в XML - PullRequest
       9

FSharpList <string>в IList <string>в XML

0 голосов
/ 24 февраля 2012

Используя код для преобразования IList<T> в FSharpList<T>, затем запишите значения списка в XML.

public static class Interop
{
    public static FSharpList<T> ToFSharpList<T>(this IList<T> input)
    {
        return CreateFSharpList(input, 0);
    }

    private static FSharpList<T> CreateFSharpList<T>(IList<T> input, int index)
    {
        if(index >= input.Count)
        {
            return FSharpList<T>.Empty;
        }
        else
        {
            return FSharpList<T>.Cons(input[index], CreateFSharpList(input, index + 1));
        }
    }
}

Я использую приведенный выше код для создания собственного списка

var fsharp_distinct = distinctWords.ToFSharpList();
var distinct_without_stopwords = Module2.stopword(fsharp_distinct);

foreach (string wd in distinct_without_stopwords)
    colwordfreq.Root.Add(new XElement(wd));

Infact, XML написан тоже, но перед выходом из цикла он дает System.NullReferenceException.Но когда функция F # вернула Tuple<string, int> с использованием того же кода, у меня не возникло проблем с записью значений Tuple в XML.

РЕДАКТИРОВАТЬ: Я был не прав в приведенном выше вопросе.Исключение с нулевой точкой фактически пришло из этого кода:

foreach (Tuple<string, int> pair in list2)
    colwordfreq.Root.Element(pair.Item1).Add(new XElement("freq", pair.Item2));

Но когда я добавил условие

if (colwordfreq.Root.Element(pair.Item1) != null)

Это исключение не дает.

1 Ответ

2 голосов
/ 24 февраля 2012

Ваш пример немного неполон, но если colwordfreq.Root.Element(pair.Item1) возвращает null для некоторых слов, это, вероятно, означает, что вы не добавляли этот элемент ранее. Может быть, вам нужно добавить элементы, написав что-то вроде:

foreach (Tuple<string, int> pair in list2) 
  colwordfreq.Root.Add                                // Add element to the root
    (new XElement(pair.Item1,                         // with the name of the word
                  new XElement("freq", pair.Item2))); // ... and the count

Кроме того, когда вы вызываете код F # из C #, стоит ознакомиться с рекомендациями по проектированию компонентов F # . Одно из предложений (которым я настоятельно рекомендую следовать) состоит в том, чтобы избегать использования специфичных для F # типов (например, FSharpList) из C #. Они действительно разработаны для F # и их трудно использовать правильно из C #.

Вы можете добавить простую функцию-обертку F #, которая предоставляет функциональность, используя IEnumerable, которая будет намного проще в использовании из C #:

let rec stopword a = 
    match a with 
    |"the"::t |"this"::t -> stopword t 
    |h::t ->h::(stopword t) 
    |[] -> [] 

module Export = 
  let StopWord (inp:seq<_>) = 
    (inp |> List.ofSeq |> stopword) :> seq<_>

Тогда вы можете просто вызвать Export.StopWord(en) из C # без явного обращения к спискам F #.

...