Replace 如何使用函数的结果更新值

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 ->

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]
目标是用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
也改成泛型,并用它来替换一行,换成一个您替换了正确单元格的版本呢?