排序和分组

时间:2013-02-02 12:05:28

标签: c# sorting grouping

我正在研究餐厅POS(Samba pos)的源代码,我在打印票证时如何格式化输出有两个问题。

下面的代码收集产品的标签,制作标题,并在标题下方对产品进行排序。

问题1:我对标题的顺序没有影响,因此输出如下:

主要课程

牛排22,50

饮料

可乐2,00

起动

汤3,50

正确的顺序应该是Starters - >主要课程 - >甜点 - >饮料 如果我可以按字母顺序对标题进行排序,我会得到很多帮助。我会将组标签更改为:1个入门者,2个主要人员等等

问题2:

产品分组在程序的早期阶段。由于程序员的选择,分组对我来说效果不佳。我在机票上有很长的清单,如:

1 x Cola 2,00

2 x Cola 4,00

有没有办法在这里对产品进行分组,以便我有:

3 x cola 6,00

这是一段代码:

if (template.GroupTemplate.Contains("{PRODUCT TAG}"))
{
    var groups = lines.GroupBy(GetMenuItemTag);
    var result = new List<string>();
    foreach (var grp in groups)
    {
        var grpSep = template.GroupTemplate.Replace("{PRODUCT TAG}", grp.Key);
        result.AddRange(grpSep.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries));
        result.AddRange(grp.SelectMany(x => FormatLines(template, x).Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)));
    }
    return result;
}

我必须排序var groups。问题是文本{PRODUCT TAG}在循环中被grp.Key替换,因此在循环之前排序var groups可能不起作用(我需要额外的循环吗?)。

将产品添加到标题中是在循环的第3行完成的。是否可以在此处对项目进行分组?

我已将整个文件转储到此处: http://pastebin.com/qFr5wN28

编辑:

这段代码用于在票务打印机上生成票证。票证看起来像这样:

BON
Datum: 2-2-2013
Tijd: 18:35    
Tafel nr.: B22    
Bon nr: 2    
------------------------------------------    
Breakfast    
- 1 Toast and Jam 1,50    
- 1 Egg, Bacon Cheese 3,99    
- 1 Toasted Bagel Cheese 2,25    
- 1 Toasted Bagel Jam 1,50    
- 2 Toast and Jam 1,50    
- 1 Egg, Bacon Cheese 3,99    
- 1 Bacon and Cheese 3,49    
- 1 Bacon and Tomato 3,49    
Deserts    
- 1 Rice Pudding 2,25    
- 1 Fruit Danish 1,50    
Main course    
- 1 Chicken Garden Wrap 5,25    
- 1 Chicken Caesar Wrap 5,75    
- 1 Canadian Wrap 6,99    
- 1 Chicken Greek Wrap 6,99

标题是我可以添加到产品的标签。 有几件事是错误的:文章上方的标题(沙漠,主要课程)随机出现。我想对它们进行排序。并非所有文章都被分组,例如“吐司和果酱”。如果我可以对标题进行排序,我会稍微更改标记。期望的输出将是这样的:

------------------------------------------    
1 Breakfast    
- 3 Toast and Jam 1,50    
- 2 Egg, Bacon Cheese 3,99    
- 1 Toasted Bagel Cheese 2,25    
- 1 Toasted Bagel Jam 1,50    
- 1 Bacon and Cheese 3,49    
- 1 Bacon and Tomato 3,49    
2 Main course    
- 1 Chicken Garden Wrap 5,25    
- 1 Chicken Caesar Wrap 5,75    
- 1 Canadian Wrap 6,99    
- 1 Chicken Greek Wrap 6,99    
3 Deserts    
- 1 Rice Pudding 2,25    
- 1 Fruit Danish 1,50

1 个答案:

答案 0 :(得分:1)

您可以使用OrderBy订购您的热线:

var groups = lines.GroupBy(GetMenuItemTag).OrderBy(l => l.Key);

您还可以遍历组并修改密钥的值。这可以通过向您的论坛添加Select投影来完成。

var groups = lines.GroupBy(GetMenuItemTag)
                  .Select(l => new { Key = template.GroupTemplate.Replace("{PRODUCT TAG}", grp.Key)
                                   , l.Value } )
                  .OrderBy(l => l.Key);

编辑:

在想到这一点后,我意识到我昨天有点蠢。我认为以下内容对您有所帮助:

//dummy data for testing purposes
List<Tuple<string, string>> items = new List<Tuple<string, string>>();
items.Add(new Tuple<string, string>("Dinner", "steak"));
items.Add(new Tuple<string, string>("Dinner", "chicken"));
items.Add(new Tuple<string, string>("Dinner", "chicken"));
items.Add(new Tuple<string, string>("Desert", "chocolate"));

var groups = (from t in items
             group t by new {Course = t.Item1, Item = t.Item2}
             into grp
                 select new
                 {
                     grp.Key.Course,
                     grp.Key.Item,
                     Quantity = grp.Count()
                 })
             .OrderBy(g => g.Course);

foreach (var g in groups)
          Console.WriteLine(string.Format("{0} {1} {2}", g.Course, g.Item, g.Quantity));

输出:

Dinner steak 1
Dinner chicken 2
Desert chocolate 1

显然你需要修改数据类型等,但查询本身应该能满足你的需要。