拼接 F# 列表
Splicing F# lists
在 F# 中将一个列表拼接到另一个列表中间的最佳方法是什么?
例如,假设列表分别为[1; 2; 3; 4]
和[7; 8; 9]
,拼接点在第一个列表的中途,结果应该是[1; 2; 7; 8; 9; 3; 4]
。
'best' 我的意思是 simplest/most 惯用的,条件是它花费的时间不超过结果长度的线性。
如果您已经在 F# 6, I would indeed follow Jackson's advice and just use the newly introduced List.insertManyAt。
如果您仍在使用旧版本并且当索引超出范围时您可以接受异常,您可以使用类似的东西:
let insertManyAt index newValues source =
let l1, l2 = List.splitAt index source
l1 @ newValues @ l2
或者如果你想要一个总函数:
let insertManyAt index newValues source =
if List.length source < index
then
None
else
let l1, l2 = List.splitAt index source
Some (l1 @ newValues @ l2)
我只使用内置的 List.insertManyAt - 无需发明任何东西。
如何解决将一个列表插入另一个列表在任意位置作为递归函数的问题的说明:
let insertManyAt index values source =
let rec aux acc n =
if n < index then function // not reached index yet
| xs, y::ys -> aux (y::acc) (n + 1) (xs, ys) // element from source
| _, [] -> List.rev acc // source exhausted, done
else function
| x::xs, ys -> aux (x::acc) n (xs, ys) // element from values
| [], y::ys -> aux (y::acc) n ([], ys) // values empty, take source instead
| [], [] -> List.rev acc // both lists empty, done
aux [] 0 (values, source)
[ 0; 1; 2 ]
|> insertManyAt 1 [ 8; 9 ]
// val it : int list = [0; 8; 9; 1; 2]
在 F# 中将一个列表拼接到另一个列表中间的最佳方法是什么?
例如,假设列表分别为[1; 2; 3; 4]
和[7; 8; 9]
,拼接点在第一个列表的中途,结果应该是[1; 2; 7; 8; 9; 3; 4]
。
'best' 我的意思是 simplest/most 惯用的,条件是它花费的时间不超过结果长度的线性。
如果您已经在 F# 6, I would indeed follow Jackson's advice and just use the newly introduced List.insertManyAt。
如果您仍在使用旧版本并且当索引超出范围时您可以接受异常,您可以使用类似的东西:
let insertManyAt index newValues source =
let l1, l2 = List.splitAt index source
l1 @ newValues @ l2
或者如果你想要一个总函数:
let insertManyAt index newValues source =
if List.length source < index
then
None
else
let l1, l2 = List.splitAt index source
Some (l1 @ newValues @ l2)
我只使用内置的 List.insertManyAt - 无需发明任何东西。
如何解决将一个列表插入另一个列表在任意位置作为递归函数的问题的说明:
let insertManyAt index values source =
let rec aux acc n =
if n < index then function // not reached index yet
| xs, y::ys -> aux (y::acc) (n + 1) (xs, ys) // element from source
| _, [] -> List.rev acc // source exhausted, done
else function
| x::xs, ys -> aux (x::acc) n (xs, ys) // element from values
| [], y::ys -> aux (y::acc) n ([], ys) // values empty, take source instead
| [], [] -> List.rev acc // both lists empty, done
aux [] 0 (values, source)
[ 0; 1; 2 ]
|> insertManyAt 1 [ 8; 9 ]
// val it : int list = [0; 8; 9; 1; 2]