【问题标题】:How to display all data from list object by combining duplicate data to display as a single object?如何通过组合重复数据显示为单个对象来显示列表对象中的所有数据?
【发布时间】:2015-08-17 02:28:31
【问题描述】:

这是我在文件中的输入存储:

   50|Carbon|Mercury|M:4;C:40;A:1
    90|Oxygen|Mars|M:10;C:20;A:00
    90|Serium|Jupiter|M:3;C:16;A:45
    85|Hydrogen|Saturn|M:33;C:00;A:3

这里50,90,90,85表示权重M,C,A表示每个元素中的比例。 p>

现在我想显示每个元素(即碳、氧等)从最高到最低,如果有多个具有相同权重的元素,将它们分组到一个单个权重并按按行星的字母顺序(火星、木星)然后元素(碳、氧等)对它们进行排序

预期输出

1)90 
  Serium;Jupiter (sorted alphabetically by planet name).
  compounds:M:3;C:16;A:45
  Oxygen;Mars
  compounds:M:10;C:20;A:00

2)85
  Hydrogen;Saturn
  M:33;C:00;A:3

3)50
  Carbon;Mercury
  M:4;C:40;A:1

这就是我的做法:

public class Planets
    {
        public int Number { get; set; }  //This field points to first cell of every row.output 50,90,90,85
        public string name { get; set; } //This field points to Second cell of every row.output Hallogen,Oxygen,Hydrogen
        public string object { get; set; } ////This field points to third cell of every row.output Mercury,Mars,Saturn
        public List<proportion> proportion { get; set; } //This will store all proportions with respect to planet object.
         //for Hallogen it will store 4,40,1.Just store number.ignore M,C,A initials.
         //for oxygen it will store 10,20,00.Just store number.ignore M,C,A initials.
    }

    public class proportion
    {
        public int Number { get; set; } 
    }

List<Planets> Planets = new List<Planets>();
                        using (StreamReader sr = new StreamReader(args[0]))
                        {
                            String line;
                            while ((line = sr.ReadLine()) != null)
                            {
                                Planets planet = new Planets();
                                String[] parts = line.Split('|');
                                planet.Number = Convert.ToInt32(parts[0]);
                                planet.name = parts[1];
                                planet.obj = parts[2];

                                String[] smallerParts = parts[3].Split(';');
                                planet.proportion = new List<proportion>();
                                foreach (var item in smallerParts)
                                {
                                    proportion prop = new proportion();
                                    prop.Number =                                    
                                    Convert.ToInt32(item.Split(':')[1]);
                                    planet.proportion.Add(prop);
                                }
                                Planets.Add(planet);
                            }
                        }
                     var data = Planets.OrderByDescending(t => t.Number).ToList();//Highest to lowest.
                      foreach (var item in data)
                        {
                            //What to do for same elements
                        }

我可以成功地在我的行星列表对象中添加所有 4 行,如下所示:

 Planets[0]:
    {
       Number:50
       name: Carbon
       object:Mercury
       proportion[0]:
                 {
                     Number:4
                 },
        proportion[1]:
                 {
                     Number:40
                 },
    proportion[2]:
                 {
                     Number:1
                 }
    }
Etc.......

我遇到的唯一问题是 显示相同数字的重量预期输出 1)并按字母顺序按行星(火星,木星)排序,然后按元素(碳、氧等)

【问题讨论】:

  • 这是显示数据还是存储数据?那么重量相同的行星应该一起存储在一个对象中,还是应该以正确的顺序显示任何给定数量的行星对象?如果是后者,您目前的显示方式如何,请提供代码,我将研究如何解决您的显示顺序问题。
  • @MeAndSomeRandoms:这只是显示数据而不是存储数据。具有相同权重的行星应合并为一个以显示火星和木星都具有相同的权重,因此我需要将它们显示在到 1 个行星,没有不同
  • 那么您是否想将所有具有相同权重的行星封装在另一个数据结构中,以便您知道在该数据结构内部都是按正确顺序具有相同权重的所有行星。或者你想在显示完整的行星列表时进行排序逻辑。我要问的是,重量相同的行星是否应该存储在一起,以便您可以按正确的顺序显示它们,或者只要显示逻辑正确排序它们,它们的存储方式无关紧要。两者都是可能的。
  • 一个简单的groupby体重就可以帮到你了,你用过吗
  • Mybe "ThenBy" 可以帮助您通过在主要属性之后按次要属性排序来获得正确的订单。示例代码为:exampleList.OrderBy(item => item.PrimaryProperty) .ThenBy(item=> item.SecondaryProperty).ToList();

标签: c# linq list sorting grouping


【解决方案1】:

我在 LinqPad 上创建了以下代码来实现您期望的结果,如果您仍需要更改,请告诉我,一个简单的 Linq 查询将有助于实现结果:

void Main()
{   
    List<Input> customList = Input.Create();

    var result = customList.GroupBy(x=>x.Weight,x=>new {x.Element1,x.Element2,x.Detail})
                       .Select(y=>new {
                                       key = y.Key,
                                       collection = y.OrderBy(z=>z.Element2)
                                      }
                               ).OrderByDescending(h=>h.key);     


    foreach(var n in result)
    {
       Console.WriteLine("Weight :: " + n.key);

       foreach(var g in n.collection)
       {
           Console.WriteLine(g.Element1 + ";" + g.Element2);
           Console.WriteLine("Compounds:" + g.Detail);
       }
    }
}

public class Input
{
  public int Weight {get; set;}
  public string Element1 {get; set;}
  public string Element2 {get; set;}
  public string Detail {get; set;}

  public Input(int w, string e1, string e2, string d)
  {
    Weight = w;
    Element1 = e1;
    Element2 = e2;
    Detail = d; 
  }

  public static List<Input> Create()
  {
    List<Input> returnList = new List<Input>();

    returnList.Add(new Input(50,"Carbon","Mercury","M:4;C:40;A:1"));
    returnList.Add(new Input(90,"Oxygen","Mars","M:10;C:20;A:00"));
    returnList.Add(new Input(90,"Serium","Jupiter","M:3;C:16;A:45"));
    returnList.Add(new Input(85,"Hydrogen","Saturn","M:33;C:00;A:3"));

    return (returnList);    
  }
}

【讨论】:

  • 转储方法不来
  • 转储方法在 linq 中不可用。
  • Edited Dump 是一种 LinqPad 方法,所以在这里不起作用,您可以使用 foreach 循环打印并打印所有相关元素,最终实体将有两个元素,键和集合,其中集合本身是一个 IOrderedEnumerable,它必须是 foreach 内的 foreach 才能打印所有详细信息。我添加了一个打印代码,虽然这将再次在单独的行中显示所有内容,但如果您想避免重印重量,它需要更多的逻辑,使用它进行分组。本质上,内部 foreach 循环需要验证权重的值,如果相同,则避免打印
  • 是的,我使用了您的代码,但重量 90 仍然打印两次。那么您如何避免这种情况??
  • 检查它现在修改了代码以完全达到您需要的结果。如果没问题,请将此标记为答案
猜你喜欢
  • 1970-01-01
  • 2018-06-06
  • 2019-12-14
  • 2011-07-03
  • 2013-03-13
  • 2019-07-04
  • 1970-01-01
  • 1970-01-01
  • 2017-01-02
相关资源
最近更新 更多