我已经编写了一个小片段,用于在NxN矩阵中提取给定单元格的任何邻居。像这样
let getNeighbours (x,y) (matrix: 'a [,]) =
let lower n = max 0 (n - 1)
let upper n = min (matrix.GetUpperBound(0)) (n + 1)
matrix.[lower x..upper x, lower y..upper y]
val arr : int [,] = [[29; 42; 0; 46; 55; 79; 18; 8]
[94; 25; 20; 45; 88; 73; 51; 69]
[62; 38; 66; 21; 55; 30; 37; 95]
[13; 35; 91; 0; 80; 15; 81; 22]
[2; 45; 94; 28; 50; 50; 35; 64]
[67; 98; 94; 63; 32; 11; 83; 23]
[38; 71; 31; 45; 52; 20; 20; 98]
[5; 4; 33; 19; 87; 17; 28; 78]]
> getNeighbours (4,0) arr;;
val it : int [,] = [[13; 35]
[2; 45]
[67; 98]]
现在它按预期工作了,我对F#Interactive显示2D数组的方式有点不满意(它翻转它们使得X轴将垂直显示,而Y轴将水平显示)但除此之外没有抱怨。
然而,我无法弄清楚如何以简洁的方式从邻居中排除给定的单元格,假设矩阵中每个单元格的值可以保持相同的值,ergo是给定单元格的唯一唯一标识符将是它的索引。
答案 0 :(得分:3)
以其他方式,基于您提出的解决方案,但使用sequence expressions:
let getNeighbours (x,y) (matrix: 'a [,]) =
let lower n = max 0 (n - 1)
let upper n = min (matrix.GetUpperBound(0)) (n + 1)
seq {
for i = lower x to upper x do
for j = lower y to upper y do
if (i, j) <> (x, y) then
yield matrix.[i, j]}
答案 1 :(得分:1)
我最终选择的方法是将数组展平,将其转换为地图并移除给定单元格的第一个出现位置。它并不像我希望的那样简洁或漂亮,也许其他人会有更好的解决方案。
let getNeighbours (x,y) (matrix: 'a [,]) =
let flatten (arr: ((int * int) * 'a) [,]) =
arr |> Seq.cast<((int * int) * 'a)>
let lower n = max 0 (n - 1)
let upper n = min (matrix.GetUpperBound(0)) (n + 1)
let hmap = matrix.[lower x..upper x, lower y..upper y]
|> Array2D.mapi (fun i j value -> ((i,j), value))
|> flatten
|> Map.ofSeq
hmap.Remove (Map.findKey (fun key value -> value = matrix.[x, y]) hmap)
|> Map.fold (fun acc _ value -> acc |> List.append [value]) []