LINQ 将项目列表转换为具有冗余值的行的查找

Posted

技术标签:

【中文标题】LINQ 将项目列表转换为具有冗余值的行的查找【英文标题】:LINQ Convert List of items to Lookup of rows with redundant values 【发布时间】:2021-05-08 19:35:17 【问题描述】:

我相信标题没有多大帮助,我会在这里尝试更好地解释......希望你能帮助我。

我有这门课

public class ItemValue

    public string SetId get; set;
    public string ItemId get; set;
    public string Value get; set;

我有一个像这个类的对象的集合

IEnumerable<ItemValue> = new List<ItemValue>()

    new ItemValue
    
        SetId = "S1",
        ItemId = "I1",
        Value = "S1I1V",
    ,
    new ItemValue
    
        SetId = "S1",
        ItemId = "I2",
        Value = "S1I2V",
    ,
    new ItemValue
    
        SetId = "S1",
        ItemId = "I3",
        Value = "S1I3V",
    ,
    new ItemValue
    
        SetId = "S2",
        ItemId = "I1",
        Value = "S2I1V",
    ,
    new ItemValue
    
        SetId = "S2",
        ItemId = "I2",
        Value = "S2I2V1",
    ,
    new ItemValue
    
        SetId = "S2",
        ItemId = "I2",
        Value = "S2I2V2",
    ,
    new ItemValue
    
        SetId = "S2",
        ItemId = "V3",
        Value = "S2I3V",
    
;

请注意,有 2 个实例的 SetId="S2"ItemId="I2" 具有不同的值

我需要的是使用 LINQ 将此集合映射到类似的东西

var expectedResult = new Lookup<string, IDictionary<string, string>>()

    ["S1"] = new Dictionary<string, string>() 
    
         ["I1"] = "S1I1V" ,
         ["I2"] = "S1I2V" ,
         ["I3"] = "S1I3V" ,
    ,
    ["S2"] = new Dictionary<string, string>() 
    
         ["I1"] = "S2I1V" ,
         ["I2"] = "S2I2V1" ,
         ["I3"] = "S2I3V" ,
    ,
    ["S2"] = new Dictionary<string, string>() 
    
         ["I1"] = "S2I1V" ,
         ["I2"] = "S2I2V2" ,
         ["I3"] = "S2I3V" ,
    
;

我自己并不擅长 LINQ,在一些不成功的 LINQ 试验和使用一堆 foreach 和 if 的丑陋解决方案之后,我现在联系您,请您对此有所了解。

如果您需要任何其他信息,请告诉我

非常感谢您!...

【问题讨论】:

【参考方案1】:

你可以用 GroupBy 和 ToDictionary/ToLookup 做类似的事情

        var dict = items.GroupBy(i => i.SetId)
            .ToDictionary(
                group => group.Key,
                group => group.ToLookup(i => i.ItemId, i => i.Value));
         dict["S2"]["I2"].ToList() // usage example

另一种选择是

var dict2 = items.ToLookup(i => (i.SetId, i.ItemId), i => i.Value);
dict2[("S2", "I2")].ToList() // usage example

【讨论】:

感谢您的回复。这个解决方案的问题是我不知道“I2”是否会有 2 个(或更多)值或“I3”或“I2”和“I3”......所以从技术上讲,我需要复制整个设置重复值的位置,因为这稍后将是一个excel文件的一行......我相信我应该在某个地方有一些“加入”来进行复制,但到目前为止我已经失败了......再次感谢你:)

以上是关于LINQ 将项目列表转换为具有冗余值的行的查找的主要内容,如果未能解决你的问题,请参考以下文章

Pandas:在多列中查找具有匹配值的行的 Pythonic 方法(分层条件)

如何获取 SQL 中具有 MAX 和 MIN 值的行的 ID

linq-select 具有所有条件的行

如何使用 linq 将平面列表转换为多级查找?

如何将具有重复值的行转换为列?

将分隔字段转换为具有名称和值的行