F# 当值(某物的id)发生变化时,及时写入记录

F# 当值(某物的id)发生变化时,及时写入记录,f#,F#,当某物的id值发生变化时,如何及时写入记录?对于某些列表,当true->false和false->true时每个记录的id 例如表 id value 1 0 2 0 2 0 2 0 1 0 2 1 --> the only changes here 2 1 1 0 2 0 --> and here (node with id 2 changed 1 -> 0 ) 1 1 --> node with id 1 changed 0 -> 1

当某物的id值发生变化时,如何及时写入记录?对于某些列表,当true->false和false->true时每个记录的id

例如表

id value
 1 0
 2 0
 2 0
 2 0
 1 0
 2 1 --> the only changes here
 2 1
 1 0
 2 0 --> and here (node with id 2 changed 1 -> 0 )
 1 1 --> node with id 1 changed 0 -> 1     
结果表

2 1
2 0
1 1
我的想法不是功能性的,有点奇怪,我正在考虑功能性的或linq的方法来实现同样的想法

                        let oop = ref (filteredsq
                                       |> Seq.distinctBy(fun (node,v,k) -> k) 
                                       |> Seq.map(fun (node,v,k) -> k, false )
                                       |> Array.ofSeq )
                        [for (node,value,key) in filteredsq do
                            let i = ref 0
                            for (k,v) in !oop do
                                if key = k && value <> v then
                                    (!oop).[!i] <- (k,value)
                                    yield node
                            i := !i + 1 ]
让oop=ref(filteredsq
|>顺序区分(乐趣(节点,v,k)->k)
|>序列映射(fun(节点,v,k)->k,false)
|>数组(0.1)
[对于filteredsq do中的(节点、值、键)]
设i=ref0
对于(k,v)in!oop do
如果key=k&&v值,则

(!oop)。[!i]我会做类似的事情

List
|> List.toSeq
|> Seq.pairwise
|> Seq.pick (fun ((fa,fb),(sa,sb)) -> if fb <> sb then Some(sa,sb) else None)
列表
|>List.toSeq
|>顺序:成对
|>Seq.pick(fun((fa,fb),(sa,sb))->如果是fb sb,那么一些(sa,sb)其他无)

我会做类似的事情

List
|> List.toSeq
|> Seq.pairwise
|> Seq.pick (fun ((fa,fb),(sa,sb)) -> if fb <> sb then Some(sa,sb) else None)
列表
|>List.toSeq
|>顺序:成对
|>Seq.pick(fun((fa,fb),(sa,sb))->如果是fb sb,那么一些(sa,sb)其他无)

已更新

open System.Collections.Generic

let filter (acc:'a) (f:('a -> 'b -> bool * 'a)) (s:'b seq) = 
    let rec iter (acc:'a) (e:IEnumerator<'b>) = 
        match e.MoveNext() with
        | false -> Seq.empty 
        | true -> match f acc e.Current with
                  | (true,newAcc) -> seq { yield e.Current; yield! iter newAcc e}
                  | (false,newAcc) -> seq { yield! iter newAcc e}
    iter acc (s.GetEnumerator())

let skipUntilChange (f : 'a -> 'b) (s : 'a seq) = 
    s |> Seq.skip 1
    |> filter (s |> Seq.head |> f)
        (fun a b -> if a = f b then false,f b else true,f b)

[(1,0);(2,0);(2,0);(2,0);(1,0);(2,1);(2,1);(1,0);(2,0);]
|> Seq.mapi (fun c (i,v) -> (i,v,c))
|> Seq.groupBy (fun (i,v,c) -> i)
|> Seq.map (snd >> skipUntilChange (fun (_,v,_) -> v))
|> Seq.concat |> Seq.sortBy (fun (i,v,c) -> c)
|> Seq.map (fun (i,v,c) -> (i,v))
|> printfn "%A"
open System.Collections.Generic
let过滤器(acc:'a)(f:('a->'b->bool*'a))(s:'b seq)=
让我们记录(附件a)(e:IEnumerator'b)(s:'a seq)=
s |>序号1
|>过滤器(s |>序列头|>f)
(乐趣a b->如果a=f b则为假,否则为真,f b)
[(1,0);(2,0);(2,0);(2,0);(1,0);(2,1);(2,1);(1,0);(2,0);]
|>Seq.mapi(趣味c(i,v)->(i,v,c))
|>Seq.groupBy(乐趣(i、v、c)->i)
|>Seq.map(snd>>skipUntilChange(乐趣(u,v,u)->v))
|>序号concat |>序号sortBy(乐趣(i、v、c)->c)
|>序列图(乐趣(i,v,c)->(i,v))
|>printfn“%A”

已更新

open System.Collections.Generic

let filter (acc:'a) (f:('a -> 'b -> bool * 'a)) (s:'b seq) = 
    let rec iter (acc:'a) (e:IEnumerator<'b>) = 
        match e.MoveNext() with
        | false -> Seq.empty 
        | true -> match f acc e.Current with
                  | (true,newAcc) -> seq { yield e.Current; yield! iter newAcc e}
                  | (false,newAcc) -> seq { yield! iter newAcc e}
    iter acc (s.GetEnumerator())

let skipUntilChange (f : 'a -> 'b) (s : 'a seq) = 
    s |> Seq.skip 1
    |> filter (s |> Seq.head |> f)
        (fun a b -> if a = f b then false,f b else true,f b)

[(1,0);(2,0);(2,0);(2,0);(1,0);(2,1);(2,1);(1,0);(2,0);]
|> Seq.mapi (fun c (i,v) -> (i,v,c))
|> Seq.groupBy (fun (i,v,c) -> i)
|> Seq.map (snd >> skipUntilChange (fun (_,v,_) -> v))
|> Seq.concat |> Seq.sortBy (fun (i,v,c) -> c)
|> Seq.map (fun (i,v,c) -> (i,v))
|> printfn "%A"
open System.Collections.Generic
let过滤器(acc:'a)(f:('a->'b->bool*'a))(s:'b seq)=
让我们记录(附件a)(e:IEnumerator'b)(s:'a seq)=
s |>序号1
|>过滤器(s |>序列头|>f)
(乐趣a b->如果a=f b则为假,否则为真,f b)
[(1,0);(2,0);(2,0);(2,0);(1,0);(2,1);(2,1);(1,0);(2,0);]
|>Seq.mapi(趣味c(i,v)->(i,v,c))
|>Seq.groupBy(乐趣(i、v、c)->i)
|>Seq.map(snd>>skipUntilChange(乐趣(u,v,u)->v))
|>序号concat |>序号sortBy(乐趣(i、v、c)->c)
|>序列图(乐趣(i,v,c)->(i,v))
|>printfn“%A”

我不确定是否完全理解您的问题,但以下内容根据您的示例给出了正确的输出。我们的想法是首先过滤掉没有正确键的值,然后使用
Seq.pairwaise
(如jpalmer的解决方案)查找值更改的位置:

let input = [ (1, 0); (2, 0); (2, 0); (2, 0); (1, 0); (2, 1); (2, 1); (1, 0); (2, 0) ]

let findValueChanges key input =
  input 
  |> Seq.filter (fun (k, v) -> k = key) // Get values with the right key
  |> Seq.pairwise                       // Make tuples with previous & next value
  |> Seq.filter (fun ((_, prev), (_, next)) -> prev <> next) // Find changing points
  |> Seq.map snd                        // Return the new key-value pair (after change)

(对于您的输入,键1的值没有变化,因为该值始终是
1,0

我不确定是否完全理解您的问题,但下面根据您的示例给出了正确的输出。我们的想法是先过滤掉没有正确键的值,然后使用
Seq.pairwaise
(如jpalmer的解决方案中所述)查找值变化的位置:

let input = [ (1, 0); (2, 0); (2, 0); (2, 0); (1, 0); (2, 1); (2, 1); (1, 0); (2, 0) ]

let findValueChanges key input =
  input 
  |> Seq.filter (fun (k, v) -> k = key) // Get values with the right key
  |> Seq.pairwise                       // Make tuples with previous & next value
  |> Seq.filter (fun ((_, prev), (_, next)) -> prev <> next) // Find changing points
  |> Seq.map snd                        // Return the new key-value pair (after change)

(对于您的输入,键1的值没有变化,因为值总是
1,0

我认为如果您定义如下函数:

let getChanges f items =
  items
  |> Seq.map (fun x -> f x, x)
  |> Seq.pairwise
  |> Seq.choose (fun ((a, _), (b, x)) -> if a <> b then Some x else None)

我认为如果你定义一个如下的函数:

let getChanges f items =
  items
  |> Seq.map (fun x -> f x, x)
  |> Seq.pairwise
  |> Seq.choose (fun ((a, _), (b, x)) -> if a <> b then Some x else None)

我只需要使用一个内部可变字典来跟踪每个键最后看到的值,并在任何值与该键上的最后一个值不同时生成(键,值):

let filterChanges (s:('a*'b) seq) =   
    let dict = new System.Collections.Generic.Dictionary<'a,'b>()
    seq {
        for (key,value) in s do
            match dict.TryGetValue(key) with
            | false,_ -> dict.[key] <- value
            | true,lastValue -> 
                if lastValue <> value then
                    yield (key,value)
                    dict.[key] <- value
    }
让过滤器更改(s:('a*'b)顺序)=
让dict=new System.Collections.Generic.Dictionary()
序号{
对于s do中的(键、值)
将dict.TryGetValue(键)与
|false,->dict[键]
如果lastValue,则
收益率(键、值)
dict.[key]过滤器更改[(1,0);(2,0);(2,0);(1,0);(2,1);(2,1);(1,0);(2,0);(1,1)];;
valit:seq=seq[(2,1);(2,0);(1,1)]

我只需要使用一个内部可变字典来跟踪每个键最后看到的值,并在任何值与该键上的最后一个值不同时产生(键,值):

let filterChanges (s:('a*'b) seq) =   
    let dict = new System.Collections.Generic.Dictionary<'a,'b>()
    seq {
        for (key,value) in s do
            match dict.TryGetValue(key) with
            | false,_ -> dict.[key] <- value
            | true,lastValue -> 
                if lastValue <> value then
                    yield (key,value)
                    dict.[key] <- value
    }
让过滤器更改(s:('a*'b)顺序)=
让dict=new System.Collections.Generic.Dictionary()
序号{
对于s do中的(键、值)
将dict.TryGetValue(键)与
|false,->dict[键]
如果lastValue,则
收益率(键、值)
dict.[key]过滤器更改[(1,0);(2,0);(2,0);(1,0);(2,1);(2,1);(1,0);(2,0);(1,1)];;
valit:seq=seq[(2,1);(2,0);(1,1)]

谢谢,但我只需要比较相同id的值。检查示例表。2 1;1 0;2 0-这里我不注册2.1->1.0,我注册2.1->2.0。谢谢,但我只需要比较相同id的值。检查示例表。2 1;1 0;2 0-这里我不注册2.1->1.0,我注册2.1->2.0。谢谢。我需要一些时间来帮助您理解:)毕竟,存在一些错误:错误3非泛型类型“System.Collections.IEnumerator”不需要任何类型参数,但这里给出了1个类型参数@nCdy:您需要
打开System.Collections.Generic
。谢谢。我需要一些时间来理解:)毕竟,有一些错误:错误3非泛型类型“System.Collections.IEnumerator”不需要任何类型参数,但这里提供了1个类型参数@nCdy:您需要
打开System.Collections.Generic
。感谢您的审阅。您的代码与示例相关:)请阅读问题中的代码以了解想法。我需要处理所有更改(使用任何if(而不仅仅是2))。抱歉,我不太了解你的代码示例。你能扩展你的示例来演示我的答案不能正确处理的情况吗?现在很好(只是我丢失了订单,但这不是什么大问题)谢谢你。[为我自己打开成对:)@nCdy