先dinctint人员编号,然后根据编号取min(时间)和max(时间)

解决方案 »

  1.   

    给你写个。假设数据全都是一天内的,可以这样测试:using System;
    using System.Collections.Generic;
    using System.Linq;namespace ConsoleApplication1
    {
        public class 记录
        {
            public string 人员;
            public string 类型;
            public TimeSpan 时间;
        }    public class 结果
        {
            public string 人员;
            public string 签到;
            public string 签退;
        }    class Program
        {
            static void Main(string[] args)
            {
                string 表1 = @"5837 签到 2014-1-6 08.53.51
     5837 签退 2014-1-6 08.53.59
     5837 签到 2014-1-6 09.03.25
     5837 签到 2014-1-6 10.04.05
     5837 签退 2014-1-6 10.04.59
     5837 签到 2014-1-6 10.26.39
     5837 签到 2014-1-6 11.16.47
     5837 签到 2014-1-6 11.57.18
     5837 签退 2014-1-6 11.59.32
     5837 签到 2014-1-6 13.36.35
     5837 签到 2014-1-6 13.53.49
     5837 签到 2014-1-6 14.51.36
     5837 签到 2014-1-6 15.11.42
     5837 签退 2014-1-6 15.38.56
     5837 签到 2014-1-6 15.45.59
     5837 签到 2014-1-6 16.39.02
     5837 签退 2014-1-6 16.41.40
     5837 签到 2014-1-6 16.47.40
     5837 签退 2014-1-6 17.22.06
     5838 签到 2014-1-6 9.0.0
     5838 签退 2014-1-6 17.33.38";
                var table1 = (from line in 表1.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
                              let sp = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
                              let sm = sp[3].Split('.')
                              let time = new TimeSpan(int.Parse(sm[0]), int.Parse(sm[1]), int.Parse(sm[2]))
                              let obj = new 记录
                              {
                                  人员 = sp[0],
                                  类型 = sp[1],
                                  时间 = time
                              }
                              orderby obj.人员, obj.时间
                              select obj).ToList();
                var table2 = 整理(table1, 0).ToList();
                Console.WriteLine("_____________________________________总共{0}行数据!", table2.Count);
                foreach (var line in table2)
                    Console.WriteLine("{0}\t{1}-{2}", line.人员, line.签到, line.签退);
                Console.WriteLine("_____________________________________按任意键结束");
                Console.ReadKey();
            }        private static IEnumerable<结果> 整理(List<记录> table1, int index)
            {
            begin:
                if (index + 1 >= table1.Count)
                    yield break; ;            var obj = table1[index];
                if (index + 1 == table1.Count || obj.类型 == "签退" || table1[index + 1].人员 != obj.人员 || table1[index + 1].类型 == obj.类型)
                {
                    yield return new 结果
                     {
                         人员 = obj.人员,
                         签退 = obj.类型 == "签退" ? obj.时间.ToString() : null,
                         签到 = obj.类型 == "签到" ? obj.时间.ToString() : null
                     };
                    index++;
                }
                else
                {
                    yield return new 结果
                    {
                        人员 = obj.人员,
                        签到 = obj.时间.ToString(),
                        签退 = table1[index + 1].时间.ToString()
                    };
                    index += 2;
                }
                goto begin;
            }
        }}
    打印结果为:
    _____________________________________总共14行数据!
    5837    08:53:51-08:53:59
    5837    09:03:25-
    5837    10:04:05-10:04:59
    5837    10:26:39-
    5837    11:16:47-
    5837    11:57:18-11:59:32
    5837    13:36:35-
    5837    13:53:49-
    5837    14:51:36-
    5837    15:11:42-15:38:56
    5837    15:45:59-
    5837    16:39:02-16:41:40
    5837    16:47:40-17:22:06
    5838    09:00:00-17:33:38
    _____________________________________按任意键结束
      

  2.   

    首先,要注意排序( orderby obj.人员, obj.时间)其次就比较简单了,要注意“整理”过程中第一个if判断,它用来当机立断仅返回只有“签到”或者只有“签退”的数据。最后就是要注意,整理过程是一个迭代器程序模式。