元组限制

时间:2011-11-24 09:41:11

标签: c# sql tuples

如何控制元组重复的循环?

有人给我一个关于算法的提示,我稍微修改了一下。

int LimCol = Convert.ToInt32(LimitColis);

result = oListTUP
         .GroupBy(x => x.Item1)
         .Select(g => new
         {
             Key = g.Key,
             Sum = g.Sum(x => x.Item2),
             Poids = g.Sum(x => x.Item3),
         })
         .Select(p => new
         {
             Key = p.Key,
             Items = Enumerable.Repeat(LimCol , p.Sum  / LimCol).Concat(Enumerable.Repeat(p.Sum  % LimCol, 1)),
             CalculPoids = p.Poids / (Enumerable.Repeat(LimCol, p.Sum / LimCol).Concat(Enumerable.Repeat(p.Sum % LimCol, 1))).Count()
         })
         .SelectMany(p => p.Items.Select(i => Tuple.Create(p.Key, i, p.CalculPoids)))
                        .ToList();

foreach (var oItem in result)
{
     Label1.Text += oItem.Item1 + "--" + oItem.Item2 + "--" + oItem.Item3 + "<br>";
}

LimCol = 3的结果 ScreenShot

正如你所看到的,我用红色来解决问题。

PS:我创建了一些不使用SQL数据的元组

 var list = new List<Tuple<string, int, decimal>>
        {
            Tuple.Create("0452632", 12, 15.0m),
            Tuple.Create("essai 49", 1, 45.0m),
            Tuple.Create("essai 49", 1, 45.0m),
            Tuple.Create("essai 49", 2, 45.0m),
            Tuple.Create("essai 49", 1, 23.0m),


        };

        int TheLimCol = 3;

        var Theresult = list
            .GroupBy(x => x.Item1)
            .Select(g => new
            {
                Key = g.Key,
                Sum = g.Sum(x => x.Item2),
                Poids = g.Sum(x => x.Item3),
            })
            .Select(p => new
            {
                Key = p.Key,
                Items = Enumerable.Repeat(TheLimCol, p.Sum / TheLimCol).Concat(Enumerable.Repeat(p.Sum % TheLimCol, 1)),

                CalculPoids = p.Poids / (Enumerable.Repeat(TheLimCol, p.Sum / TheLimCol).Concat(Enumerable.Repeat(p.Sum % TheLimCol, 1))).Count()

            })
            .SelectMany(p => p.Items.Select(i => Tuple.Create(p.Key, i, p.CalculPoids)))
            .ToList();

        foreach (var oItem in Theresult)
        {
            Label1.Text += oItem.Item1 + "--" + oItem.Item2 + "--" + oItem.Item3 + "<br>";
        }

实际输出:

0452632--3--3,0
0452632--3--3,0
0452632--3--3,0
0452632--3--3,0
0452632--0--3,0
essai 49--3--79,0
essai 49--2--79,0

预期结果:

0452632--3--3,75
0452632--3--3,75
0452632--3--3,75
0452632--3--3,75
essai 49--3--79,00
essai 49--2--79,00

1 个答案:

答案 0 :(得分:1)

问题在于你的“.Concat(Enumerable.Repeat(p.Sum%TheLimCol,1)”。即使余数(p.Sum%TheLimCol)等于0,你也要添加一个元素。

这应该有效:

        var result = list
            .GroupBy(x => x.Item1)
            .Select(g => new
            {
                Key = g.Key,
                Sum = g.Sum(x => x.Item2),
                Poids = g.Sum(x => x.Item3),
            })
            .Select(p => new
            {
                Key = p.Key,
                Items = Enumerable.Repeat(limCol, p.Sum / limCol).Concat(Enumerable.Repeat(p.Sum % limCol, p.Sum % limCol > 0 ? 1 : 0)),
                CalculPoids = p.Poids / Enumerable.Repeat(limCol, p.Sum / limCol).Concat(Enumerable.Repeat(p.Sum % limCol, 1)).Count()
            })
            .SelectMany(p => p.Items.Select(i => Tuple.Create(p.Key, i, p.CalculPoids)))
            .ToList();

在这种特定情况下,我建议使用Linq的替代语法(或根本不使用Linq):

        var query = from x in list
                    group x by x.Item1 into g
                    let sum = g.Sum(x => x.Item2)
                    let poids = g.Sum(x => x.Item3)
                    let remainder = sum % limCol
                    let items = Enumerable.Repeat(limCol, sum / limCol).Concat(Enumerable.Repeat(remainder, remainder > 0 ? 1 : 0))
                    select new
                    {
                        Key = g.Key,
                        Items = items,
                        CalculPoids = poids / items.Count()
                    };


        var result = query.SelectMany(p => p.Items.Select(i => Tuple.Create(p.Key, i, p.CalculPoids)));