【问题标题】:How to get data out of List<Dictionary<string, string>如何从 List<Dictionary<string, string> 中获取数据
【发布时间】:2018-08-19 16:02:56
【问题描述】:

我在操作List&lt;Dictionary&lt;string,string&gt;&gt;&gt; SSRList 以轻松从中获取数据时遇到问题。我已经走到这一步了:

var bleh = SSRList
    .Where(x => x.ContainsKey("ServiceTechHrs"))  //Scott Shauf total tech hours
    .Where(x => x.ContainsKey("ServiceTech") && x.ContainsValue("Scott Shauf"))
    .Select(x => x["ServiceTechHrs"])
    .Where(x => x != "")
    .Sum(x => Convert.ToDouble(x))
    .Dump("All Scott Shauf TechNumbers");

这回答了 scott 作为技术人员总共工作了多少小时。

我该如何回答“Scott 和 Doug 作为技术人员或工程师花了多少小时?”我在使用允许我询问 lambda 表达式的语法方面遇到困难......同样,我想知道如何在 Dict Keys 上执行“GroupBy”?

【问题讨论】:

  • 对于这种查询,我认为List&lt;Dictionaty&lt;string,string&gt;&gt; 是存储数据的错误类型。使用专门的课程会容易得多。
  • 为什么x.ContainsValue("Scott Shauf") 而不是x["ServiceTech"] == "Scott Shauf" 因为我认为这是您要检查的条目。否则任何值都可能有他的名字,比如有一个主管条目。
  • 我想你想要.Where(x =&gt; (x.ContainsKey("ServiceTech") &amp;&amp; (x["ServiceTech"] == "Scott" || x["ServiceTech"] == "Doug")) || (x.ContainsKey("Engineer") &amp;&amp; (x["Engineer"] == "Scott" || x["Engineer"] == "Doug")))。至于分组,你在这里有两个方面,现有的键和该键的值,所以它实际上取决于你想要分组的确切内容,因为首先过滤现有的键然后对值进行分组是最有意义的。跨度>
  • 您开始询问this question。然后,当没有答案时,您选择继续使用List&lt;Dictionary&lt;string, string&gt;&gt; 并开始按照该曲目询问questions。但是你走错了方向。您应该选择一个将键作为属性,将值作为属性值的类。这将使 LINQ 查询变得微不足道。现在您总是需要寻找具有 (Key == x && Value == y) 的键/值对。
  • 我认为这个问题与您之前的@​​987654323@ 重复,因为这是关于如何查询List&lt;Dictionary&lt;string, string&gt;&gt; 的另一个问题。

标签: c# linq dictionary lambda


【解决方案1】:

正如其他人指出的那样,使用Dictionary&lt;string, string&gt; 来表示某些结构化类型会让您摆脱 LINQ 的所有美感。但是,如果您因为某些(有问题的)设计原因不得不走这条路,那么尽快使用强类型将会把它带回来。

看来你喜欢使用类似的东西

public interface ITechnician
{
    string ServiceTech { get; }
    double ServiceTechHours { get; } // or should it be TimeSpan?
}

我会写一些代码来做这些脏活:

public static class MyExtensions
{
    public static IEnumerable<ITechnician> OfTypeTechnician(this IEnumerable<IDictionary<string, string>> records)
    {
        foreach (var record in records)
        {
            if (!record.TryGetValue("ServiceTech", out var serviceTech)) continue;
            if (!record.TryGetValue("ServiceTechHrs", out var serviceTechHrsStr) || !double.TryParse(serviceTechHrsStr, out var serviceTechHrs)) continue;
            yield return new Technician { ServiceTech = serviceTech, ServiceTechHours = serviceTechHrs };
        }
    }

    private class Technician : ITechnician
    {
        public string ServiceTech { get; set; }
        public double ServiceTechHours { get; set; }
    }
}

休息很容易:

var records = new[]
{
    new Dictionary<string, string> { { "ServiceTech", "Scott Shouf"}, { "ServiceTechHrs", "4711" } },
    new Dictionary<string, string> { { "ServiceTech", "Scott Shouf"}, { "ServiceTechHrs", "0815" } },
    new Dictionary<string, string> { { "ServiceTech", "Scott Shouf"}, { "ServiceTechHrs", "not convertible to double" } },
    new Dictionary<string, string> { { "ServiceTech", "Someone Else"}, { "ServiceTechHrs", "42" } },
    new Dictionary<string, string> { { "Animal", "Giraffe" } }
};

var allScottShaufTechNumbers = records
    .OfTypeTechnician()
    .Where(t => t.ServiceTech == "Scott Shouf")
    .Sum(t => t.ServiceTechHours);
// 5526

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多