如何在列表中移动项目
输入列表如下所示:let list = [1;2;3;4;5]
输出列表看起来像下列之一:
[1;2;3;5;4]
.........>
[2;1;3;4;5]
...>......
情节扭曲:我希望能够移动列表中的任何索引
据我所知,这不是你想用F#或函数式语言做的事情,但它是我的程序必备的。
我相信这可以使用递归和高阶(HO)函数来完成,但由于我对HO的知识非常有限,我尝试使用递归来解决这个问题。
我在列表中向下移动项目的方法包括一个简单的递归,索引和列表作为参数,如下所示:
let rec moveDownAt index list =
match index, list with
| -1, _ -> list
| 0, h1::h2::t -> h2::h1::t
| index, h::t -> h::moveDownAt (index - 1) t
| _, [] -> list
然而,为了向另一个方向移动,我需要引用前面的“头部”,我假设我会在第三个匹配线| index, h::t -> h::moveDownAt (index - 1) t
上遇到问题,我执行h ::,因为我添加了头部列表(如果我添加该参数,那将是前一个下一个调用)。
答案 0 :(得分:2)
在两个元素上切换位置意味着一个向上移动,一个向下移动 使用以下代码简单就可以解决问题:
let moveUpAt index list = moveDownAt (index-1) list
这将取代索引使“索引向下移动”变成“索引向上移动”。
答案 1 :(得分:1)
基本思想如下:首先,返回列表的n
元素。然后追加除n
元素之外的其余元素,因为您已经返回了它。这是代码:
let MoveToTop index xs =
List.nth xs index // take nth item
:: // and prepend it to the beginning of the
// original list, except the nth element
(
xs // original data
|> List.mapi
(fun i x -> i, x) // associate each element with its ordinal index
|> List.filter
(fun (i, _) -> i <> index) // allow only the elements whose index
// is not equal to requested index
|> List.map snd // remove the index from the data
// as we no longer need it
)
// test
[1; 2; 3; 4; 5]
|> MoveToTop 1 // don't forget, the index is zero-based
|> printfn "%A"
// output: [2; 1; 3; 4; 5]
请注意,如果index
超出列表的长度,则会抛出ArgumentException
。
递归算法也是可能的,但由于过多的数据创建和执行过多的计算,它肯定会降低性能。