gpt4 book ai didi

f# - 在 F# 中从具有 N 个不同索引的序列中取出 N 个元素

转载 作者:行者123 更新时间:2023-12-04 11:16:28 25 4
gpt4 key购买 nike

我是 F# 的新手,正在寻找一个函数,它接受 N*indexes 和一个序列并给我 N 个元素。如果我有 N 个索引,它应该等于 concat Seq.nth index0, Seq.nth index1 .. Seq.nth indexN 但它应该只扫描序列中的 indexN 个元素 (O(N)) 而不是 index0+index1+.. .+indexN (O(N^2))。

总而言之,我正在寻找类似的东西:

//For performance, the index-list should be ordered on input, be padding between elements instead of indexes or be ordered when entering the function
seq {10 .. 20} |> Seq.takeIndexes [0;5;10]
Result: 10,15,20

我可以通过使用 seq { yield... } 来实现这一点,并有一个索引计数器来标记何时应该传递某些元素,但如果 F# 提供了一个很好的标准方式,我宁愿使用它。

谢谢 :)...

添加:我做了以下。它有效但不漂亮。欢迎提出建议
let seqTakeIndexes (indexes : int list) (xs : seq<int>) =
seq {
//Assume indexes is sorted
let e = xs.GetEnumerator()
let i = ref indexes
let curr = ref 0

while e.MoveNext() && not (!i).IsEmpty do
if !curr = List.head !i then
i := (!i).Tail
yield e.Current

curr := !curr + 1
}

最佳答案

当您想通过索引访问元素时,使用序列并不是一个好主意。序列被设计为允许顺序迭代。我会将序列的必要部分转换为数组,然后按索引选择元素:

let takeIndexes ns input = 
// Take only elements that we need to access (sequence could be infinite)
let arr = input |> Seq.take (1 + Seq.max ns) |> Array.ofSeq
// Simply pick elements at the specified indices from the array
seq { for index in ns -> arr.[index] }

seq [10 .. 20] |> takeIndexes [0;5;10]

关于您的实现 - 我认为它不能变得更加优雅。在实现需要以交错方式从多个来源获取值的函数时,这是一个普遍问题 - 没有优雅的编写方式!

但是,您可以使用像这样的递归以函数方式编写它:
let takeIndexes indices (xs:seq<int>) = 
// Iterates over the list of indices recursively
let rec loop (xe:IEnumerator<_>) idx indices = seq {
let next = loop xe (idx + 1)
// If the sequence ends, then end as well
if xe.MoveNext() then
match indices with
| i::indices when idx = i ->
// We're passing the specified index
yield xe.Current
yield! next indices
| _ ->
// Keep waiting for the first index from the list
yield! next indices }
seq {
// Note: 'use' guarantees proper disposal of the source sequence
use xe = xs.GetEnumerator()
yield! loop xe 0 indices }

seq [10 .. 20] |> takeIndexes [0;5;10]

关于f# - 在 F# 中从具有 N 个不同索引的序列中取出 N 个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3323088/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com