如何从 List返回 csv 值

发布于 2024-12-09 02:39:22 字数 481 浏览 0 评论 0原文

我有 List 包含名称、年份和值的项目集合,如下所示

Names   years  Values
=====   =====  =====
Smith   2010   777
Smith   2011   999
Jones   2007   01
Jones   2008   03
Jones   2009   05
Jones   2010   06
Jones   2011   09

我想编写一个 LINQ 查询,返回一个 CSV 值字符串,其中“名称”后跟“值”从最早的年份(在本例中为 2007 年)开始的每一年,如果“年份”数据丢失/不存在(在本例中 Smith 没有任何年份值) 2007,2008,2009) 然后将结果代入 0

如下:

Results:
Smith,0,0,0,777,999
Jones,01,03,05,06,09

I have List<item> containing an items collections of name, years and values as follows

Names   years  Values
=====   =====  =====
Smith   2010   777
Smith   2011   999
Jones   2007   01
Jones   2008   03
Jones   2009   05
Jones   2010   06
Jones   2011   09

I want to write a LINQ query that returns me a a string of CSV values with the "name" followed by "values" for each year beginning with the earliest year (in this case its 2007) and if the "years" data is missing/absent (in this case Smith does not have any values for years 2007,2008,2009) then substitute the result with 0

As follows:

Results:
Smith,0,0,0,777,999
Jones,01,03,05,06,09

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

z祗昰~ 2024-12-16 02:39:22

您想要一个 Linq 解决方案,所以这里是:

list
    .Select(i=>i.Name)
    .Distinct()
    .Select(name => 
       name + "," + 
       String.Join(",", (from y in list.Select(i=>i.Year).Distinct().OrderBy(y=>y)
                        join item in list.Where(i=>i.Name == name) 
                        on y equals item.Year into outer
                    from o in outer.DefaultIfEmpty()
                    select ((o == null) ? "0" : o.Value.ToString()) 
                         ).ToArray()));

您可以在此处查看它的实际效果:
http://www.coderun.com/ide/?w=9QASFzOJrECO3SJDdUo93A
只需点击“运行”,

Linq 就不是很强大吗?

You wanted a Linq solution so here it is:

list
    .Select(i=>i.Name)
    .Distinct()
    .Select(name => 
       name + "," + 
       String.Join(",", (from y in list.Select(i=>i.Year).Distinct().OrderBy(y=>y)
                        join item in list.Where(i=>i.Name == name) 
                        on y equals item.Year into outer
                    from o in outer.DefaultIfEmpty()
                    select ((o == null) ? "0" : o.Value.ToString()) 
                         ).ToArray()));

You can see it in action here:
http://www.coderun.com/ide/?w=9QASFzOJrECO3SJDdUo93A
Just hit "Run"

Isn't Linq Powerful or what...

您可以这样做:

var minYear = items.Min(i => i.Year);
var maxYear = items.Max(i => i.Year);

var names = items.Select(i => i.Name).Distinct();

using (TextWriter writer = …)
{
    foreach (var name in names)
    {
        writer.Write(name);

        for (int y = minYear; y <= maxYear; y++)
        {
            writer.Write(',');

            var value = items.Where(i => i.Name == name && i.Year == y)
                             .Select(i => i.Value)
                             .SingleOrDefault();

            writer.Write(value);
        }

        writer.WriteLine();
    }
}

不过,这将不必要地多次遍历 items 集合。因此,如果速度对您来说很重要,您可能应该使用一本或多本字典。

You could do it like this:

var minYear = items.Min(i => i.Year);
var maxYear = items.Max(i => i.Year);

var names = items.Select(i => i.Name).Distinct();

using (TextWriter writer = …)
{
    foreach (var name in names)
    {
        writer.Write(name);

        for (int y = minYear; y <= maxYear; y++)
        {
            writer.Write(',');

            var value = items.Where(i => i.Name == name && i.Year == y)
                             .Select(i => i.Value)
                             .SingleOrDefault();

            writer.Write(value);
        }

        writer.WriteLine();
    }
}

This will unnecessarily walk though the items collection many times, though. So if speed of this was important to you, you should probably use one or more dictionaries.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文