如果键匹配,如何从元组中提取一个值

Posted

技术标签:

【中文标题】如果键匹配,如何从元组中提取一个值【英文标题】:How to pull one tvalue from Tuple if key matches 【发布时间】:2021-01-30 06:22:36 【问题描述】:

在我的程序中,我加入了两个 IEnumerables 并将它们转换为字典,如下所示:

//list1 is a list of all contracts, list2 is a list of special contracts
var list1 = //List of objects
Var list2 = //List of objects 
var combined = List1.Join(list2, c=> s.contractNumber, dto => dto.contract, (s, dto) => dto)
.ToDictonary( x => x.Contract, y => y.Date);

var final = list1.Select(contractNumber =>
var number = contract.ContractNumber;
contract.Date = combined.ContainsKey(number) ? combined[number] : string.Empty;

简短的版本是这样的:我们使用 list1 来填充我们在前端显示的表格,但业务请求的更改需要显示来自单独 API 调用的信息。 List1 没有包含日期​​字段,但 list2 包含。所以我们将属性添加到list1中,然后使用字典根据键值对填充属性。

他们再次请求在前端显示来自 list2 的另一个字段,所以我想使用这样的元组:

.ToDictionary(x=>x.Contract, y => Tuple.Create(y.Date, y.Type));

但我在这里更新代码时遇到了困难:

contract.Date = combined.ContainsKey(number) ? combined[number] : string.Empty; //It breaks due to converting tuple<string, string> to string

使用基于键的元组中的值之一填充字段的最佳方法是什么?

【问题讨论】:

尝试 null 而不是 string.Empty 问题是当条件为真时,组合的[数字]部分。 IT 想要提取与该键关联的值,但现在有两个值,所以它很困惑。我需要它只使用 Value1 使用:combined.Item2 combined[number].Item2 有效。谢谢! 我不明白你的代码。例如,var final = list1.Select(contractNumber =&gt; 行声明了一个带有参数 contractNumber 的 lambda,该参数在任何地方都没有使用。之后出现一个变量contract,它没有在任何地方声明。另外我不确定属性s.contractNumbercontract.ContractNumber 是否不同,或者相同的属性是否存在转录错误(以c 而不是C 开头)。 【参考方案1】:

在我看来,list1 是一系列相似的项目,我们称它们为Contracts。每个Contract 都有一个属性ContractNumber

List2 也是一系列相似的项目。不知道里面有什么,但我们称他们为ContractDates。每个ContractDate 都有属性Contract 和一个Date

哦,我差点忘了:ContractDate.Contract 是 ContractDate 所属的 Contract 的 ContractNumber。所以如果 ContractDate.Contract 等于 14,那么这个 ContractDate 就属于编号为 14 的 Contract。

最后:关系是一对零或一:每个 Contract 都有零个或一个 ContractDate,每个 ContractDate 恰好属于一个 Contract,即外键 Contract 所指的 Contract。

所以可能有没有 ContractDate 的合同

您似乎想要所有合同的(几个属性),每个合同都有其ContractDate 的日期。如果合同没有 ContractDate,那么您希望使用 Date 的默认值(在您的情况下为 String.Empty)

您是对的,每当您使用项目表时,其中每个项目都有来自另一个表的零个或多个项目,并且您想要组合这两个表,您使用某种连接。

如果您想要项目,每个项目都有其唯一的其他项目,请使用加入。如果您希望每个项目都有零个或多个其他项目,请使用 GroupJoin

所以GroupJoin在以下情况下:

有零个或多个学生的学校 有零个或多个订单的客户 具有零个或多个 ContractDates 的合同(在您的情况下:零个或一个)

如果你想反过来使用 Join:

他们就读的唯一一所学校的学生 下订单的客户的订单 外键引用的合同的合同日期。

你有你的问题,因为你走错了方向:你应该使用 one of the overloads of GroupJoin 而不是 Join。

在您的情况下,最好使用带有参数 resultSelector 的重载:对于每个具有零个或多个 ContractDates(在您的情况下:零或一)的合约,创建一个新对象:

IEnumerable<Contract> contracts = ...
IEnumerable<ContractDate> contractDates = ...

var contractsWithTDates = contracts.GroupJoin(contractDates,

    contract => contract.ContractNumber,      // from every contract take the number
    contractDate => contractDate.Contract,    // from every contractDate take the foreign key

    // parameter resultSelector: for every Contract, with its zero or more ContractDates
   // make one new object:
   (contract, contractDatesOfThisContract) => new ...);

现在你想要什么作为结果对象:

我想要合约的几个参数

我想要唯一的 ContractDate 的日期,如果没有 ContractDate,则为 String.Empty

常量字符串 defaultContractDate = String.Empty; var contractsWithTDates =contracts.GroupJoin(contractDates, ...

 (contract, contractDatesOfThisContract) => new
 
     // Select the zero or more properties of the contract that you want:
     ContractNumber = contract.ContractNumber,
     CustomerId = contract.CustomerId,
     ...

     // Select the properties of the contract dates of this contract that you want
     // if there is one: use the date
     // if there is none: use the defaultContractDate
     // if there is more than one, which you don't expect, use the first contractDate
     Date = contractDatesOfThisContract
            .Select(contractDate => contractDate.Date)
            .FirstOrDefault() ?? defaultContractDate,
 );

简而言之:对于 contractDatesOfThisContract 中的每个 Date(您最多期望其中一个),选择属性 Date。从生成的日期序列中,取第一个,或者如果没有第一个,则返回“默认”,在这种情况下为空。

操作员 ?? (null-coalescing operator):如果 FirstOrDefault 的结果非 null,则使用该值,如果为 null,则使用 defaultContractDate。

【讨论】:

感谢您的详细回复。你对情况有大致的了解。然而,问题不在于合同日期。这是相当容易提供的初始请求。当他们回来说哦,我们还需要显示另一个属性时,问题就来了。 cmets 中为我的问题提供了快速解决方案——使用元组工作我只是错过了 .Item1/.item2 语法

以上是关于如果键匹配,如何从元组中提取一个值的主要内容,如果未能解决你的问题,请参考以下文章

从元组中提取向量

从元组中的字典创建数据框

查询 Python 字典以从元组中获取值

如果子字符串存在,则从元组中删除项目

从元组的元组中创建一个列表

我可以像在 for 循环中从数组中索引项目一样从元组中检索项目吗?