1

我试图根据日期时间升序和 pcName(string) 的 9 条记录基于主列表制作子列表。

我的排序子列表需要如下所示

对象列表 1:

2615,2019-11-22 16:03:22。150测试1

2615,2019-11-22 16:03:22。200 ,测试1

2615,2019-11-22 16:03:22。250测试1

2615,2019-11-22 16:03:22。300 ,测试1

对象列表 2:

2615,2019-11-22 16:03:22。350测试2

2615,2019-11-22 16:03:22。400 ,测试2

对象列表 3:

2615,2019-11-22 16:03:22。450测试1

2615,2019-11-22 16:03:22。500 ,测试1

对象列表 4:

2615,2019-11-22 16:03:22。550测试3

这个对象列表需要按照 ObjectList[0] ,ObjectList[1] ,ObjectList[2] 和 ObjectList[3] 的顺序取

我在下面提到了我的示例代码

但这仅为我提供了 3 个基于Test1、Test2 和 Test3以及 9 个子列表的子列表集(Item1)过滤器,但我想要上面的 4 个子列表。我想在哪里更改代码??请帮我

private void button_Click(object sender, EventArgs e)
        {
            List<Identity> listOfIdentity = new List<Identity>()
            {
               new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.550"),PcName="Test3"},                              
               new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.300"), PcName="Test1"},                            
               new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.350"), PcName="Test2"},
               new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.400"), PcName="Test2"},
               new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.200"), PcName="Test1"},
               new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.500"), PcName="Test1"},
               new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.250"), PcName="Test1"},
               new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.450"), PcName="Test1"},
               new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.150"), PcName="Test1"}              
            };
            List<Identity> sortedIdentity = listOfIdentity.OrderBy(x => x.QCTime).ThenBy(x => x.PcName).ToList(); // here i order by time and then pc name

            var items1 = listOfIdentity.OrderBy(x => x.QCTime).ThenBy(x => x.PcName).GroupBy(x => x.PcName).Select(grp => grp.ToList()).ToList(); //sub list create based with **Test1, Test2 & Test3** (3 sub lists)
            var items2 = listOfIdentity.OrderBy(x => x.QCTime).ThenBy(x => x.PcName).GroupBy(x => new { x.QCTime, x.PcName }).Select(grp => grp.ToList()).ToList(); //sub list create based with each time and pc name (9 sublists)
        }

        class Identity
        {
            public int id { get; set; }
            public DateTime QCTime { get; set; }
            public string PcName { get; set; }
        }
4

3 回答 3

2

这是我使用的解决方案Linq.Aggregate

private void button_Click(object sender, EventArgs e)
{
    List<Identity> listOfIdentity = new List<Identity>()
    {
        new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.550"), PcName="Test3"},
        new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.300"), PcName="Test1"},
        new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.350"), PcName="Test2"},
        new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.400"), PcName="Test2"},
        new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.200"), PcName="Test1"},
        new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.500"), PcName="Test1"},
        new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.250"), PcName="Test1"},
        new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.450"), PcName="Test1"},
        new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.150"), PcName="Test1"}
    };
    List<Identity> sortedIdentity = listOfIdentity.OrderBy(x => x.QCTime).ThenBy(x => x.PcName).ToList(); // here i order by time and then pc name
    var result = sortedIdentity.Skip(1).Aggregate(new List<List<Identity>> { new List<Identity> { sortedIdentity[0] } }, (lists, curr) =>
    {
        if (curr.PcName == lists.Last()[0].PcName)
            lists.Last().Add(curr);
        else
            lists.Add(new List<Identity> { curr });
        return lists;
    });
}

它遍历每个元素并检查它的PcName是否与以前的相同。如果是,则在同一个列表中,否则使用此元素创建新列表。


编辑:Matt.G建议的更优雅的解决方案

    List<Identity> sortedIdentity = listOfIdentity.OrderBy(x => x.QCTime).ThenBy(x => x.PcName).ToList();
    var result = sortedIdentity.Aggregate(new List<List<Identity>>(), (lists, curr) => 
   { 
        if (curr.PcName == lists.LastOrDefault()?.FirstOrDefault()?.PcName)
            lists.Last().Add(curr);
        else
            lists.Add(new List<Identity> { curr });
        return lists;
    });
于 2019-12-02T19:36:10.723 回答
0

没有专门用于一次性对连续元素进行分组的内置 LINQ 方法。不过,创建一个并不难。可以在这个答案中找到一个实现,签名如下:

public static IEnumerable<IEnumerable<TSource>> SplitByPredicate<TSource>(
    this IEnumerable<TSource> source,
    Func<TSource, TSource, bool> splitPredicate);

您可以使用它来解决您的问题,如下所示:

var sublists = listOfIdentity
    .OrderBy(x => x.QCTime)
    .ThenBy(x => x.PcName)
    .SplitByPredicate((x, y) => x.PcName != y.PcName);

可以在此处找到不同的实现,其签名略有不同:

public static IEnumerable<List<TSource>> GroupConsecutiveByKey<TSource, TKey>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector);

...可以这样使用:

var sublists = listOfIdentity
    .OrderBy(x => x.QCTime)
    .ThenBy(x => x.PcName)
    .GroupConsecutiveByKey(x => x.PcName);
于 2019-12-03T01:18:11.183 回答
-1

由于您尝试按 DateTime 列进行分组,并且该列仅在 MilliSeconds 中变化,因此不会按照您的期望进行分组。我修改了你的代码如下:

class Identity
    {
        public int id { get; set; }
        public DateTime QCTime { get; set; }
        public string PcName { get; set; }

        public string QCTimeForGroup
        {
            get
            {
                if (QCTime.Millisecond <= 300)
                {
                    return "SL1";
                }
                else if (QCTime.Millisecond > 300 && QCTime.Millisecond <= 400)
                {
                    return "SL2";
                }
                else if (QCTime.Millisecond > 400 && QCTime.Millisecond <= 500)
                {
                    return "SL3";
                }

                return "SL4";
            }
        }
    }


private void button_Click(object sender, EventArgs e)
        {
            List<Identity> listOfIdentity = new List<Identity>()
            {
               new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.550"),PcName="Test3"},                              
               new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.300"), PcName="Test1"},                            
               new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.350"), PcName="Test2"},
               new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.400"), PcName="Test2"},
               new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.200"), PcName="Test1"},
               new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.500"), PcName="Test1"},
               new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.250"), PcName="Test1"},
               new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.450"), PcName="Test1"},
               new Identity() {id= 2615,QCTime=DateTime.Parse("2019-11-22 16:03:22.150"), PcName="Test1"}              
            };
            List<Identity> sortedIdentity = listOfIdentity.OrderBy(x => x.QCTime).ThenBy(x => x.PcName).ToList(); // here i order by time and then pc name

            var items1 = listOfIdentity.OrderBy(x => x.QCTime).ThenBy(x => x.PcName).GroupBy(x => x.PcName).Select(grp => grp.ToList()).ToList(); //sub list create based with **Test1, Test2 & Test3** (3 sub lists)
            var items2 = listOfIdentity.OrderBy(x => x.QCTime).ThenBy(x => x.PcName).GroupBy(x => new { x.QCTime, x.PcName }).Select(grp => grp.ToList()).ToList(); //sub list create based with each time and pc name (9 sublists)
            var items3 = listOfIdentity.OrderBy(x => x.QCTime).ThenBy(x => x.PcName)
                        .GroupBy(x => new { x.QCTimeForGroup, x.PcName }).Select(grp 
                        => grp.ToList()).ToList(); 
        }
于 2019-12-02T19:31:20.657 回答