F #: InvalidOperationException: входная последовательность имеет недостаточное количество элементов?

У меня есть функция, которая возвращает последовательность записей. В этой функции я начинаю построение списка с пустой фиктивной записи (вероятно, есть способ сделать это лучше), потому что мне нужно накапливать похожие записи, поэтому я «заправляю насос» пустой записью. Вот мой код:

let consolidate(somethings:seq<Something>) =
    let mutable results = ResizeArray()
    let mutable accumulatedSomething = {Foo = ""; Bar = ""; Count = 0;}
    for s in somethings do
        if s.Foo = accumulatedSomething.Foo && s.Bar = accumulatedSomething.Bar then
           accumulatedSomething <- {Foo = s.Foo; Bar = s.Bar;
                                    Count = s.Count + accumulatedSomething.Count}
        else
            results.Add(accumulatedSomething)    
            accumulatedSomething <- e
    results |> Seq.cast |> Seq.skip 1

Если у вас есть способ сделать это лучше, я все слышу (я все еще мыслю процедурно), но меня все еще интересует ответ на этот конкретный вопрос. Позже в своем коде я пытаюсь распечатать список:

somethings |> Seq.iter( fun s -> printfn "%A" s)

Это отлично работает, когда в списке есть что-то. Но если список пуст и единственной записью, которая была в списке, была пропущенная пустая начальная запись, то эта строка завершается ошибкой с InvalidOperationException с сообщением The input sequence has an insufficient number of elements?

Почему это происходит и как это исправить?


person User    schedule 22.06.2013    source источник


Ответы (1)


Проблема возникает, когда somethings - пустой список.

В этом случае results пусто, и вызов Seq.skip 1 в пустом списке завершается ошибкой.

Я думаю, что элегантным решением было бы изменить последнюю строку на

match results.Length with
| 0 -> results |> Seq.cast
| _ -> results |> Seq.cast |> Seq.skip 1
person John Palmer    schedule 22.06.2013
comment
Ага ты прав. Почему-то я подумал, что ошибка произошла после того, как консолидация уже вернулась, а не внутри консолидации. Я предполагаю, потому что отладчик остановился на строке somethings |> Seq.iter( fun s -> printfn "%A" s), а не на строке внутри функции консолидации. Как бы вы это исправить? - person User; 22.06.2013