如何使用LINQ迭代并显示组

时间:2017-03-21 18:45:23

标签: c# linq

我有list:我需要显示这些内容,以便每个艺术家的信息列在相应的艺术家下面。

到目前为止,我所尝试的每个艺术家都列出了相同的数据。

public class Artist
{
    public string Name { get; set; }
    public string Car { get; set; }
    public int ID { get; set; }

    public List<Artist> Profile()
    {
        var artistList = new List<Artist>();

        // Artist: 1

        artistList.Add(new Artist() { Name = "Nick Cage", Car = "Corvette", ID = 1 });
        artistList.Add(new Artist() { Name = "Nick Cage", Car = "Porsche 718", ID = 1 });
        artistList.Add(new Artist() { Name = "Nick Cage", Car = "Audi", ID = 1 });

        // Artist: 2

        artistList.Add(new Artist() { Name = "Ryan Rynolds", Car = "Lotus", ID = 2 });
        artistList.Add(new Artist() { Name = "Ryan Rynolds", Car = "Alfa Romeo", ID = 2 });
        artistList.Add(new Artist() { Name = "Ryan Rynolds", Car = "Jaguar", ID = 2 });

        return artistList;

    }
}

使用Windows Form MessageBox我需要显示数据,以便在加载MessageBox时将结果安排如下。

Nick Cage
ID 1
Porsche 718
Audi
BMW

Ryan Rynolds
ID 2
Lotus
Alfa Romeo
Jaguar

对于本演示,我将所有代码都放在表单代码中的单个方法中:

    private readonly Artist _artist = null;
    public Form1()
    {
        InitializeComponent();
        _artist = new Artist();
    }

    private void DisplayArtist()
    {
        StringBuilder content = new StringBuilder();

        var group = _artist.Profile().GroupBy(t => 
        t.Name).Select(grp => grp.FirstOrDefault());

        foreach (var person in group)
        {
            content.Append(person.Name);
            content.AppendLine();

            // Append names to list


            foreach (var profile in group)
            {
              // Append profile to list
              // Tried using second loop but not getting expected results
            }

            content.AppendLine();

        }

        DialogResult result1 = 
            MessageBox.Show(content.ToString(),
            "Artist Profile", MessageBoxButtons.YesNo);

    }

    private void Form1_Load(object sender, EventArgs e)
    {
        DisplayArtist();
    }
}

4 个答案:

答案 0 :(得分:3)

你快到了。首先,你将这样的事情分组:

var grouped = p.GroupBy(a => new { a.ID, a.Name });

(我使用了name和id的组合,所以我可以从密钥中检索两者)

然后你可以遍历每个小组:

foreach (var g in grouped)
{
    Console.WriteLine(g.Key.Name);
    Console.WriteLine(g.Key.ID);
    Console.WriteLine(string.Join("\n", g.Select(c => c.Car)));
    Console.WriteLine();
}

这里我只是写入控制台,但你可以为一个消息框组装一个字符串或者你正在用它做什么。

答案 1 :(得分:2)

除了每个分组中的第一个项目之外,不要删除除Select(grp => grp.FirstOrDefault())以外的所有项目。然后,当您迭代结果时,您将拥有一个IGrouping,其Key属性具有名称,并且可以自行迭代以获取该组中的每个单独的艺术家对象。

var people = _artist.Profile().GroupBy(t => t.Name);

foreach (var person in people)
{
    content.AppendLine(person.Key); // The name of the person

    foreach (var profile in person)
    {
        content.AppendLine(profile.Car); //The name of each car
    }
}

答案 2 :(得分:0)

有很多方法可以实现你的要求。如果您仍想使用_artist.Profile().GroupBy(t => t.Name);代码,则以下是其中之一:

var group = _artist.Profile().GroupBy(t =>
            t.Name);

var result = string.Join("\n", group.Select(a =>
{
      var carStr = a.Select(c => c.Car);
      return $"{a.FirstOrDefault()?.Name}\n{a.FirstOrDefault()?.ID}\n{string.Join("\n", carStr)}";
}));

答案 3 :(得分:0)

另一种方式(我真的认为它是一个更好的整体设计)是创建你的对象艺术家:

public class Artist
{
    public string Name { get; set; }
    public List<string> Cars { get; set; }
    public int ID { get; set; }

    public List<Artist> Profile()
    {
        var artistList = new List<Artist>();

        // Artist: 1
        artistList.Add(new Artist()
        {
            ID = 1,
            Name = "Nick Cage",
            Car = new List<string>
            {
                "Corvette",
                "Porsche 718",
                "Audi"
            }
        });

        // Artist 2
        artistList.Add(new Artist()
        {
            ID = 2,
            Name = "Ryan Rynolds",
            Car = new List<string>
            {
                "Lotus",
                "Alfa Romeo",
                "Jaguar"
            }
        });

        return artistList;

    }
}

优点:

  • 无数据冗余
  • 更少的记忆(当然,只有在巨大的名单上才能注意到)
  • 无需分组
  • 在现实世界中更有意义,因为只有一位名叫Nick Cage的艺术家,并且他有一份汽车清单

要实现您想要的目标,请执行以下操作:

foreach(Artist a in artistList)
{
    Console.WriteLine(a.Name);
    Console.WriteLine(a.ID);

    foreach(string car in a.Cars)
    {
        Console.WriteLine(car);
    }
}