gpt4 book ai didi

f# - 如何简化 F# 数组中不存在于另一个数组中的元素的筛选?

转载 作者:行者123 更新时间:2023-12-04 02:15:57 24 4
gpt4 key购买 nike

我有 2 个 F# 数组要比较。对于其中一个函数,我必须找到数组 1 中的所有元素,这些元素在数组 2 中没有具有相同键字段的元素。

我设法得到了一些有用的东西,但我必须承认我现在尝试阅读它时有点斜眼。我觉得开发人员以后必须修改它。

findWorkItemToClose 函数中是否有更简单易读的方式来表达这一点?

/// Gets the ICCM call number given a work item reference id. The reference id may have a dash number suffix on the call number.
let getIccmCallNumberFromReference (referenceId:string) =
if referenceId.Contains("-") then
referenceId.Substring(0, referenceId.IndexOf("-"))
else
referenceId

/// Gets the TFS work items where the ReferenceId no longer exists in the set of open Iccm calls.
let findWorkItemsToClose (allWorkItems:WorkItem[]) (iccmCalls:Iccm.IccmCall[]) =
let openStates = Set.ofList ["New"; "Approved"; "Commited"]
let openWorkItems = allWorkItems |> Array.filter (fun wi -> Set.contains wi.State openStates)
openWorkItems
|> Array.filter(fun wi ->
not (iccmCalls
|> Array.exists (fun ic ->
ic.CallNumber = getIccmCallNumberFromReference (wi.Fields.["ReferenceId"].Value.ToString()))))

更新:发布备用版本 1(根据答案中的建议)和使用数组理解的备用版本 2。

/// ALT 1: Gets the TFS work items where the ReferenceId no longer exists in the set of open Iccm calls.
let findWorkItemsToClose1 (allWorkItems : WorkItem []) (iccmCalls : Iccm.IccmCall []) =
let callNumbers = iccmCalls |> Array.map (fun ic -> ic.CallNumber) |> Set.ofArray
let openStates = Set.ofList ["New"; "Approved"; "Commited"]
let openWorkItems = allWorkItems |> Array.filter (fun wi -> Set.contains wi.State openStates)

openWorkItems
|> Seq.groupBy (fun wi -> getIccmCallNumberFromReference(wi.Fields.["ReferenceId"].Value.ToString()))
|> Seq.filter (fun (callNumber, _) -> not (Set.contains callNumber callNumbers))
|> Seq.collect snd
|> Seq.toArray

/// ALT 2: Gets the TFS work items where the ReferenceId no longer exists in the set of open Iccm calls.
let findWorkItemsToClose2 (allWorkItems : WorkItem []) (iccmCalls : Iccm.IccmCall []) =
let iccmCallNumbers = iccmCalls |> Array.map (fun ic -> ic.CallNumber) |> Set.ofArray
let openStates = Set.ofList ["New"; "Approved"; "Commited"]
let openWorkItems = allWorkItems |> Array.filter (fun wi -> Set.contains wi.State openStates)

[|
for workItem in openWorkItems do
let callNumberOnWorkItem = getIccmCallNumberFromReference(workItem.Fields.["ReferenceId"].Value.ToString())
if not (Set.contains callNumberOnWorkItem iccmCallNumbers) then
yield workItem
|]

最佳答案

不能 100% 确定这就是您想要的,但如果我是正确的,您可以:

  1. 获取不同的 CallNumbers(如果它们尚未不同,否则只需使用您的原始数组;不确定是将其设为集合还是数组 [perf concern maybe])
  2. 按 ReferenceID 中的 CallNumber 对您的工作项目进行分组;给你一个seq<string * seq<WorkItem>>
  3. 过滤以仅保留不在第 1 步中定义的数组/集合中的键(电话号码)。
  4. 最后“加入”工作项并使其成为一个数组

我使用 Seq 来避免在每个步骤中创建数组(内存问题),并且还以(对我而言)似乎更简单的方式重写了另一个函数。

let getIccmCallNumberFromReference (referenceId : string) =
match referenceId.IndexOf "-" with
-1 -> referenceId
| 0 -> "" // to be consistent with the original function
| index -> referenceId.[.. index - 1]

let findWorkItemsToClose (allWorkItems : WorkItem []) (iccmCalls : Iccm.IccmCall []) =
// see comments if you choose to use a set instead of an array
let callNumbers = iccmCalls |> Array.distinctBy (fun ic -> ic.CallNumber) // |> Set.ofArray

allWorkItems
|> Seq.groupBy (fun wi -> getIccmCallNumberFromReference(wi.Fields.["ReferenceId"].Value.ToString()))
|> Seq.filter (fun (callNumber, _) -> not (Array.contains callNumber callNumbers)) // replace Array.contains by Set.contains
|> Seq.collect snd
|> Seq.toArray

关于f# - 如何简化 F# 数组中不存在于另一个数组中的元素的筛选?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33621128/

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