Replace 如何使用函数的结果更新值
su值如下所示:Replace 如何使用函数的结果更新值,replace,f#,logic,Replace,F#,Logic,su值如下所示: let rec insert v i l = match i, l with | 0, xs -> v::xs | i, x::xs -> x::insert v (i - 1) xs | i, [] -> failwith "index out of range" let rec remove i l = match i, l with | 0, x::xs -> xs | i, x::xs ->
let rec insert v i l =
match i, l with
| 0, xs -> v::xs
| i, x::xs -> x::insert v (i - 1) xs
| i, [] -> failwith "index out of range"
let rec remove i l =
match i, l with
| 0, x::xs -> xs
| i, x::xs -> x::remove (i - 1) xs
| i, [] -> failwith "index out of range"
let replace (r,s,v : int) =
remove (s-1) su.[r-1]
insert (char(string(v))) (s-1) su.[r-1]
目标是用replace函数生成的新列表替换su中的一个列表,然后将该结果保存为新su。这就是我到目前为止所做的
[['5'; '3'; '*'; '*'; '7'; '*'; '*'; '*'; '*'];
['6'; '*'; '*'; '1'; '9'; '5'; '*'; '*'; '*'];
['*'; '9'; '8'; '*'; '*'; '*'; '*'; '6'; '*'];
['8'; '*'; '*'; '*'; '6'; '*'; '*'; '*'; '3'];
['4'; '*'; '*'; '8'; '*'; '3'; '*'; '*'; '1'];
['7'; '*'; '*'; '*'; '2'; '*'; '*'; '*'; '6'];
['*'; '6'; '*'; '*'; '*'; '*'; '2'; '8'; '*'];
['*'; '*'; '*'; '4'; '1'; '9'; '*'; '*'; '5'];
['*'; '*'; '*'; '*'; '8'; '*'; '*'; '7'; '9']]
调用replace(2,2,4)后,su应按如下方式结束:
let rec insert v i l =
match i, l with
| 0, xs -> v::xs
| i, x::xs -> x::insert v (i - 1) xs
| i, [] -> failwith "index out of range"
let rec remove i l =
match i, l with
| 0, x::xs -> xs
| i, x::xs -> x::remove (i - 1) xs
| i, [] -> failwith "index out of range"
let replace (r,s,v : int) =
remove (s-1) su.[r-1]
insert (char(string(v))) (s-1) su.[r-1]
除非您坚持递归执行,否则以下操作可能会奏效:
[['5'; '3'; '*'; '*'; '7'; '*'; '*'; '*'; '*'];
['6'; '4'; '*'; '1'; '9'; '5'; '*'; '*'; '*'];
['*'; '9'; '8'; '*'; '*'; '*'; '*'; '6'; '*'];
['8'; '*'; '*'; '*'; '6'; '*'; '*'; '*'; '3'];
['4'; '*'; '*'; '8'; '*'; '3'; '*'; '*'; '1'];
['7'; '*'; '*'; '*'; '2'; '*'; '*'; '*'; '6'];
['*'; '6'; '*'; '*'; '*'; '*'; '2'; '8'; '*'];
['*'; '*'; '*'; '4'; '1'; '9'; '*'; '*'; '5'];
['*'; '*'; '*'; '*'; '8'; '*'; '*'; '7'; '9']]
但是我自己对这段代码不太满意
如果您坚持递归地使用您的代码,那么您可以通过这个示例了解如何/如何处理您自己的代码 要转换列表列表,需要两个级联的list.map。对于List.mapi,还提供了元素的索引。 使用列和行索引,很容易在正确的位置进行替换
let su =
[['5'; '3'; '*'; '*'; '7'; '*'; '*'; '*'; '*'];
['6'; '*'; '*'; '1'; '9'; '5'; '*'; '*'; '*'];
['*'; '9'; '8'; '*'; '*'; '*'; '*'; '6'; '*'];
['8'; '*'; '*'; '*'; '6'; '*'; '*'; '*'; '3'];
['4'; '*'; '*'; '8'; '*'; '3'; '*'; '*'; '1'];
['7'; '*'; '*'; '*'; '2'; '*'; '*'; '*'; '6'];
['*'; '6'; '*'; '*'; '*'; '*'; '2'; '8'; '*'];
['*'; '*'; '*'; '4'; '1'; '9'; '*'; '*'; '5'];
['*'; '*'; '*'; '*'; '8'; '*'; '*'; '7'; '9']]
let replaceV s v i c =
if i + 1 = s then v else c
let replaceL r s v i l =
let replaceV' = replaceV s v
match i with
| _ when r = i + 1 -> l |> List.mapi replaceV'
| _ -> l
// x y value
let replace r s v =
let replace' = replaceL r s v
su |> List.mapi replace'
replace 2 2 '4'
我有办法解决你的问题。它由两个功能组成。第一个替换列表中位置i处的值v。第二个函数调用第一个函数并用数字i替换列表
let su =
[['5'; '3'; '*'; '*'; '7'; '*'; '*'; '*'; '*'];
['6'; '*'; '*'; '1'; '9'; '5'; '*'; '*'; '*'];
['*'; '9'; '8'; '*'; '*'; '*'; '*'; '6'; '*'];
['8'; '*'; '*'; '*'; '6'; '*'; '*'; '*'; '3'];
['4'; '*'; '*'; '8'; '*'; '3'; '*'; '*'; '1'];
['7'; '*'; '*'; '*'; '2'; '*'; '*'; '*'; '6'];
['*'; '6'; '*'; '*'; '*'; '*'; '2'; '8'; '*'];
['*'; '*'; '*'; '4'; '1'; '9'; '*'; '*'; '5'];
['*'; '*'; '*'; '*'; '8'; '*'; '*'; '7'; '9']]
let replace su col row r =
List.mapi (fun i xs ->
List.mapi (fun j x ->
if (i+1)=col && (j+1)=row
then r else x) xs) su
replace su 2 2 '4'
您可以在F#REPL中测试这两个选项:
let rec replaceInList v i lst =
match i, lst with
| _, [] -> []
| 1, x::xs -> v::xs
| i, x::xs -> x::replaceInList v (i-1) xs
let rec replaceInMatrix v i j matrix =
match i, matrix with
| _, [] -> []
| 1, x::xs -> (replaceInList v j x)::xs
| i, x::xs -> x::replaceInMatrix v (i-1) j xs
第二个功能基本上是第一个功能的重复。也许有一种方法可以创建一个更通用的实现,但不幸的是,我的F#不够流利,无法想出更好的解决方案。也许还有其他人…为什么不把
replace
也改成泛型,并用它来替换一行,换成一个您替换了正确单元格的版本呢?