2016-10-09 3 views
2

Я пытаюсь написать модуль в F #, который удалит каждый третий элемент из списка и вернет новый список без этих элементов.Удалите каждый третий элемент из списка F #

, например

let input = [ 1 .. 15 ] 

printfn "List with elements eliminated: %A" (Program1.remove input) 

который sould дать этот выход

List with elements eliminated: [1; 2; 4; 5; 7; 8; 10; 11; 13; 14] 

Что я пытался до сих пор

module Program1 = 
open System 
let remove list1= 
    let collectList = List.iteri (fun i x -> if i%3 <> 0 then x) list1 
    collectList 
[<EntryPoint>] 
let main argv = 
let list = [ 1; 2; 3] 
printfn "new List is %A" (Program1.remove list) 
0 

Теперь я ПОЛУЧАТЬ ошибку, и я пытался весь день, чтобы решить Это. Спасибо заранее

+2

Какие сообщения об ошибках вы получили? –

+0

Некоторые подсказки для рекурсивного подхода здесь: http://stackoverflow.com/questions/18906178/delete-third-element-in-f-list/18906483#18906483 –

ответ

1

Для этой ошибки:

error FS0001: Type mismatch. Expecting a 
    'unit list' 
but given a 
    'int list' 
The type 'unit' does not match the type 'int' 

проблема исходит от линии if i%3 <> 0 then x. Это if-выражение без предложения else, и оно должно иметь тип unit и выводить результаты вывода типа в x, являющемся типом unit. Для получения более подробной информации об условиях F #, читайте https://docs.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/conditional-expressions-if-then-else.

EDIT: Кроме того, List.iteri не делает то, что вы намереваетесь сделать, потому что List.iteri не возвращает список, он возвращает unit. Вам нужны функции, такие как List.map, List.filter, List.choose, List.foldBack, чтобы решить вашу проблему.

Прочитайте принятый ответ с этого поста, чтобы получить представление о том, как подойти к этой проблеме (вам нужно будет внести небольшие изменения): Getting every nth Element of a Sequence

Существует также более простой подход с использованием List.foldBack для создания в результате список.

+0

Возможно, добавьте немного о том, что 'List.iteri' также возвращает 'unit'. Кроме того, хотя связанный ответ правильный, здесь можно сделать более простой подход (и там тоже), просто используя 'List.foldBack' – Sehnsucht

+0

' let list = [1..15] ' ' let r1 = List.filter (fun x -> x% 3 <> 0) list' 'printfn" новый Список% A "r1' Это было мое окончательное решение. Спасибо за подсказки. Моя проблема заключалась в том, что я пытался удалить каждый элемент trid для каждого типа списка, но в моем случае у меня всегда будет отсортированный список, поэтому его можно легко сделать с помощью List.filter. Спасибо –

0

Я не уверен, что если вы пытаетесь фильтровать каждое третье значение или каждое значение divideable на 3.

Если его первый случай, чем один функциональный подход может быть, как это

//safe take and skip fn (no exceptions) 
let take x xs = if List.length xs >= x then List.take x xs else [] 
let skip x xs = if List.length xs >= x then List.skip x xs else [] 
let rec remove x xs = 
    //effectively this drops every xnt element 
    let head = take (x - 1) xs 
    let tail = skip x xs 
    match tail with 
    | [] -> head 
    | _ -> List.append head (remove x tail) 

let x = ["One";"Two";"Three";"Four";"Five";"Six";"Seven";"Eight";"Nine";"Ten"] 
remove 3 x 

Однако это довольно тяжелый вес ;-)
так лучше подход может быть, как вы почти нашли

let x = ["One";"Two";"Three";"Four";"Five";"Six";"Seven";"Eight";"Nine";"Ten"] 
let indices = [1 .. List.length x] 

List.zip indices x 
|> List.filter (fun (x,_) -> x % 3 <> 0) 
+1

Не забудьте только получить предметы в конце и с F # 4.0 есть 'List.indexed', который возвращает список элементов, дополненных их индексами, вы можете переписать его' x |> List.indexed |> List.filter (fun (i, _) -> i% 3 <> 0) |> List.map snd' – Sehnsucht

+0

@Sehnsucht да, это еще лучше – robkuz

Смежные вопросы