首页 新闻 会员 周边

dataTable 运算的问题!路过的大侠帮忙看下吧!

0
悬赏园豆:10 [已解决问题] 解决于 2014-06-30 09:06

求跟好的思路或者方法解决!

如图:测试数据源格式 这个查询数据库的已经保证了这个格式 

dt列 name相等 那么下一条减去上一条 差 值相加 如果如果差值大于5或者小于0过滤

并且 下一条时间要大于上一条时间

比如 name为张三 (4-1)+(78-4) 这样的格式 但是78-4大于5而已时间也不对 过滤

 (4-1)+(79-78)这样的格式

最后记录保存 相关值

我的代码实现

  DataTable dt = new DataTable();
            dt.Columns.Add(new DataColumn("csID"));
            dt.Columns.Add(new DataColumn("Name"));
            dt.Columns.Add(new DataColumn("value"));
            dt.Columns.Add(new DataColumn("Time"));
            DataRow row = dt.NewRow();
            row[0] = "1";
            row[1] = "张三";
            row[2] = "1";
            row[3] = DateTime.Now;
            dt.Rows.Add(row);

            DataRow row1 = dt.NewRow();
            row1[0] = "1";
            row1[1] = "张三";
            row1[2] = "4";
            row1[3] = DateTime.Now.AddDays(1);
            dt.Rows.Add(row1);

            DataRow row2 = dt.NewRow();
            row2[0] = "1";
            row2[1] = "张三";
            row2[2] = "78";
            row2[3] = DateTime.Now.AddDays(-1);
            dt.Rows.Add(row2);


            DataRow row21 = dt.NewRow();
            row21[0] = "1";
            row21[1] = "张三";
            row21[2] = "79";
            row21[3] = DateTime.Now.AddDays(2);
            dt.Rows.Add(row21);

            DataRow rowt = dt.NewRow();
            rowt[0] = "1";
            rowt[1] = "张三";
            rowt[2] = "80";
            rowt[3] = DateTime.Now.AddDays(-5);
            dt.Rows.Add(rowt);


            DataRow row3 = dt.NewRow();
            row3[0] = "2";
            row3[1] = "李四";
            row3[2] = "2";
            row3[3] = DateTime.Now;
            dt.Rows.Add(row3);

            DataRow row4 = dt.NewRow();
            row4[0] = "2";
            row4[1] = "李四";
            row4[2] = "5";
            row4[3] = DateTime.Now.AddDays(1);
            dt.Rows.Add(row4);


            DataRow d = dt.NewRow();
            d[0] = "2";
            d[1] = "李四";
            d[2] = "5";
            d[3] = DateTime.Now.AddDays(-1);
            dt.Rows.Add(d);

            DataRow row5 = dt.NewRow();
            row5[0] = "3";
            row5[1] = "王五";
            row5[2] = "3";
            row5[3] = DateTime.Now.AddDays(-1);
            dt.Rows.Add(row5);

            var sum = 0;
            var resultDt = new DataTable();
            resultDt.Columns.Add("ID");
            resultDt.Columns.Add("Name");
            resultDt.Columns.Add("starMile");
            resultDt.Columns.Add("endMile");
            resultDt.Columns.Add("sumMile");
            var isFlag = true;
            var fistMile = "";
            for (int i = 0; i < dt.Rows.Count - 1; i++)
            {
                var nowValue = dt.Rows[i]["value"].ToString();
                var nextValue = dt.Rows[i + 1]["value"].ToString();
                if (dt.Rows[i]["Name"] == dt.Rows[i + 1]["Name"])
                {
                    //如果下一条时间小于上一条时间终止
                    if (DateTime.Parse(dt.Rows[i + 1]["Time"].ToString()) < DateTime.Parse(dt.Rows[i]["Time"].ToString())) continue;

                    //差值累加 如果大于5 并且小于过滤掉
                    var tempSum = int.Parse(nextValue) - int.Parse(nowValue);
                    if (tempSum < 5 && tempSum > 0)
                    {
                        //第一次的值 
                        if (fistMile=="")
                        {
                            fistMile = nowValue;
                        }
                        sum += tempSum;
                        isFlag = false;
                    }
                }
                //name不相等 并且 isFlag为flase 代表当前name相同的有多条(这里过滤王五)
                if (dt.Rows[i]["Name"] != dt.Rows[i + 1]["Name"])
                {
                    if (!isFlag)
                    {
                        resultDt.Rows.Add(dt.Rows[i]["csID"], dt.Rows[i]["Name"], fistMile, nowValue, sum);
                    }
                    fistMile = "";
                    sum = 0;
                }
            }

运行结果:

求优化或者 更好的实现方法 谢谢 

s_p的主页 s_p | 初学一级 | 园豆:138
提问于:2014-06-26 21:58
< >
分享
最佳答案
0
foreach (var g in dt.Rows.Cast<DataRow>().GroupBy(x => x["Name"]))
            {
                int sum = 0;
                var gList = g.ToList();
                if (gList.Count < 2)
                {
                    continue;
                }
                for (var i = 0; i < gList.Count - 1; i++)
                {
                    if (Convert.ToDateTime(gList[i + 1]["Time"]) < Convert.ToDateTime(gList[i]["Time"])) continue;
                    var x = Convert.ToInt32(gList[i + 1]["value"]) - Convert.ToInt32(gList[i]["value"]);
                    if (x > 0 && x < 5)
                    {
                        sum += x;
                    }
                }
                resultDt.Rows.Add(gList[0]["csID"], g.Key, gList[0]["value"], gList[gList.Count - 1]["value"], sum);
            }

 

还是建议用强实体。
收获园豆:8
幻天芒 | 高人七级 |园豆:37175 | 2014-06-26 23:25
其他回答(1)
0

好做法是转成list实体集合,然后用linq查询,坏做法是对datatable做linq查询

收获园豆:2
吴瑞祥 | 园豆:29449 (高人七级) | 2014-06-26 22:20

转化list 循环的逻辑基本上还是和我一样的 ? 这样的话意义不大 嗯 其实我希望linq 虽然性能会小点 谢谢你怎么晚 回答我的问题 谢谢

支持(0) 反对(0) s_p | 园豆:138 (初学一级) | 2014-06-26 22:23
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册