DataTable列上多值运算

1、从网上找了个中缀算法(也不知道什么前缀后缀,抱歉),可以对字符串表达式进行运算

2、有些时候还是会用到ASCII码表的

char c = expression[k];//expression为一字符串
int intAsciiCode = (int)c;

3、里面用到了解决多种字符串日期显示格式,转换为日期类型的办法

DateTime time = DateTime.Now;

DateTimeFormatInfo dtfi = new CultureInfo("zh-CN", true).DateTimeFormat;
DateTime.TryParseExact(strTime, new string[] { "yyyyMMdd", "yyyy.M.d", "d-M-yyyy", "d-M月-yyyy", "yyyy-M-d", "yyyy_M_d" }, dtfi, DateTimeStyles.None, out time);//strTime为字符串类型日期

  1  public class DataTableCompute
  2     {
  3         /// <summary>
  4         /// 对DataTabella行上的列根据运算式计算
  5         /// </summary>
  6         /// <param name="dicDecimal">数值类型表达式键值对</param>
  7         /// <param name="dicTime">时间类型表达式键值对</param>
  8         /// <param name="row">DataTable表上的行</param>
  9         public static void ComputeColumns(Dictionary<string, string> dicDecimal, Dictionary<string, string> dicTime, DataRow row)
 10         {
 11             if (dicDecimal != null && dicDecimal.Count > 0)
 12             {
 13                 foreach (KeyValuePair<string, string> kvp in dicDecimal)
 14                 {
 15                     GetExpressionByType(row, kvp, "decimal");
 16                 }
 17             }
 18             if (dicTime != null && dicTime.Count > 0)
 19             {
 20                 foreach (KeyValuePair<string, string> kvp in dicTime)
 21                 {
 22                     GetExpressionByType(row, kvp, "time");
 23                 }
 24             }
 25
 26         }
 27
 28         private static void GetExpressionByType(DataRow row, KeyValuePair<string, string> kvp, string type)
 29         {
 30             string result = kvp.Key;
 31             string expression = kvp.Value;
 32             string[] cols = expression.Split(new char[] { ‘(‘, ‘)‘, ‘+‘, ‘-‘, ‘*‘, ‘/‘, ‘\\‘ },StringSplitOptions.RemoveEmptyEntries);
 33             for (int m = 0; m < cols.Length; m++)
 34             {
 35                 if (type == "time")
 36                 {
 37                     DateTime time = DateTime.Now;
 38                     if (cols[m].ToLower() != "now")
 39                     {
 40                         DateTimeFormatInfo dtfi = new CultureInfo("zh-CN", true).DateTimeFormat;
 41                         if (!DateTime.TryParseExact(row[cols[m]].ToString(), new string[] { "yyyyMMdd", "yyyy.M.d", "d-M-yyyy", "d-M月-yyyy", "yyyy-M-d", "yyyy_M_d" }, dtfi, DateTimeStyles.None, out time))
 42                         {
 43                             time = DateTime.Now;
 44                         }
 45                     }
 46                     cols[m] = (time.Year * 12 + time.Month).ToString();
 47                 }
 48                 else
 49                 {
 50                     double d = 0;
 51                     if (double.TryParse(row[cols[m]].ToString(), out d))
 52                     {
 53                         d = Math.Round(d, 3);
 54                     }
 55                     cols[m] = d.ToString();
 56                 }
 57             }
 58             StringBuilder newExpression = new StringBuilder();
 59             int n = 0;
 60             for (int k = 0; k < expression.Length; k++)
 61             {
 62                 char c = expression[k];
 63                 int intAsciiCode = (int)c;
 64                 if (intAsciiCode >= 40 && intAsciiCode <= 47)
 65                 {
 66                     newExpression.Append(c.ToString() + " ");
 67                     continue;
 68                 }
 69                 if (c == ‘F‘ || c == ‘n‘)
 70                 {
 71                     newExpression.Append(cols[n] + " ");
 72                     n++;
 73                 }
 74             }
 75             string str = newExpression.ToString();
 76             row[result] = CalculateResult(str);
 77         }
 78         private static double CalculateResult(string expre)
 79         {
 80             List<string> temp = getColuExpression(expre);
 81             try
 82             {
 83                 while (temp.Count > 1)
 84                 {
 85                     for (int i = 0; i < temp.Count; i++)
 86                     {
 87                         double resultTemp = 0;
 88                         if (temp[i] == "+")
 89                             resultTemp = Convert.ToDouble(temp[i - 2]) + Convert.ToDouble(temp[i - 1]);
 90                         else if (temp[i] == "-")
 91                             resultTemp = Convert.ToDouble(temp[i - 2]) - Convert.ToDouble(temp[i - 1]);
 92                         else if (temp[i] == "*")
 93                             resultTemp = Convert.ToDouble(temp[i - 2]) * Convert.ToDouble(temp[i - 1]);
 94                         else if (temp[i] == "/")
 95                             resultTemp = Convert.ToDouble(temp[i - 2]) / Convert.ToDouble(temp[i - 1]);
 96                         else
 97                             continue;
 98                         temp[i - 2] = resultTemp.ToString();
 99                         temp.RemoveAt(i);
100                         temp.RemoveAt(i - 1);
101                         break;
102                     }
103                 }
104             }
105             catch (Exception ex)//计算表达式的值错误,导致无法运算
106             {
107                 temp.Clear();
108                 temp.Add("0");
109             }
110             return Convert.ToDouble(temp[0]);
111         }
112         private static List<string> getColuExpression(string exp)
113         {
114             System.Text.ASCIIEncoding asc = new System.Text.ASCIIEncoding();
115             Stack st = new Stack();
116             string[] temp = exp.Split(new char[] { ‘ ‘ }, StringSplitOptions.RemoveEmptyEntries);
117             List<string> value = new List<string>();
118
119             for (int i = 0; i < temp.Length; i++)
120             {
121                 int num = (int)asc.GetBytes(temp[i])[0];
122                 if (num < 48 && num > 39)
123                 {
124                     if (st.Count > 0)
125                     {
126                         string operatorStr = st.Peek().ToString();
127                         if (temp[i] == "*" || temp[i] == "/")
128                         {
129                             if (temp[i + 1] == "(")
130                             {
131                                 st.Push(temp[i]);
132
133                                 continue;
134                             }
135                             else
136                             {
137                                 if (operatorStr == "(")
138                                 {
139                                     st.Push(temp[i]);
140                                     continue;
141                                 }
142                                 else if (operatorStr == "*" || operatorStr == "/")
143                                 {
144                                     value.Add(st.Pop().ToString());
145                                     st.Push(temp[i]);
146                                     continue;
147                                 }
148                                 else
149                                 {
150                                     st.Push(temp[i]);
151                                     continue;
152                                 }
153                             }
154                         }
155                         else if (temp[i] == "+" || temp[i] == "-")
156                         {
157                             if (operatorStr == "(")
158                             {
159                                 st.Push(temp[i]);
160                                 continue;
161                             }
162                             else
163                             {
164                                 value.Add(st.Pop().ToString());
165                                 if (st.Count > 0 && st.Peek().ToString() != "(")
166                                 {
167                                     value.Add(st.Pop().ToString());
168                                 }
169                                 st.Push(temp[i]);
170                                 continue;
171                             }
172                         }
173                         else if (temp[i] == "(")
174                         {
175                             st.Push(temp[i]);
176                             continue;
177                         }
178                         else
179                         {
180                             if (i + 1 == temp.Length)
181                             {
182                                 value.Add(st.Pop().ToString());
183                                 st.Pop();
184                                 while (st.Count > 0)
185                                     value.Add(st.Pop().ToString());
186                                 break;
187                             }
188                             else
189                             {
190                                 value.Add(st.Pop().ToString());
191                                 st.Pop();
192                                 continue;
193                             }
194                         }
195                     }
196                     else
197                     {
198                         st.Push(temp[i]);
199                         continue;
200                     }
201                 }
202                 else if (i + 1 == temp.Length)
203                 {
204                     value.Add(temp[i]);
205                     value.Add(st.Pop().ToString());
206                     while (st.Count > 0)
207                         value.Add(st.Pop().ToString());
208                     break;
209                 }
210                 else
211                 {
212                     value.Add(temp[i]);
213                     continue;
214                 }
215             }
216             return value;
217         }
218     }

DataTable列计算类

时间: 2024-10-20 17:09:18

DataTable列上多值运算的相关文章

【Excel】SUMIF 或用 筛选器 实现挑选含有某些字段的值,然后把这些值所对应的后面某列上的值相加

Background: 挑选含有某些字段的值,然后把这些值所对应的后面某列上的值相加.比如挑选下表中,所有带有“MX104”这个字段的值,然后把它的后面total那一列的值相加. Solution: 随便选个A16这个位置来记录这个数,公式是 =SUMIF(A2:A12,"*MX104*",D2:D12)  ,得到的值是107784.6,就是含有MX104的这几个单元格的D列的值的相加. 使用筛选器也可以达到相同效果: 给A1加上筛选器,如上图,然后筛选MX104如下图 但是要注意的是

获取DataTable某一列的所有值

/// <summary>/// 获取某一列的所有值/// </summary>/// <typeparam name="T">列数据类型</typeparam>/// <param name="dtSource">数据表</param>/// <param name="filedName">列名</param>/// <returns>&

深入理解计算机系统(2.2)---布尔代数以及C语言上的位运算

本文转载地址:http://www.cnblogs.com/zuoxiaolong/p/computer6.html 布尔代数上的位运算 布尔代数是一个数学知识体系,它在0和1的二进制值上演化而来的. 我们不需要去彻底的了解这个知识体系,但是里面定义了几种二进制的运算,却是我们在平时的编程过程当中也会遇到的.这四种运算分别是或.与.非和异或.下图展示了在布尔代数的知识体系中,对这四种运算的定义. 从左至右依次是非.与.或以及异或.这个图阐述的是针对一位二进制的运算结果,我们可以将其扩大到N位二进

索引列上的统计 &lt;第一篇&gt;

一.索引在查询优化中的角色 SQL Server的查询优化器是基于开销的优化器.它通过确认选择性.数据的唯一性以及过滤数据(通过WHERE或JOIN子句)所使用的列来决定最佳的数据访问机制.统计与索引一同存在,但是它们也作为断言的一部分存在于没有索引的列上. 作为谓词引用的列中数据分布的最新信息帮助优化器确定所使用的查询策略.在SQL Server中,这个信息以统计的形式维护,这对于基于开销的优化器创建一个有效的查询执行计划是很重要的.通过统计,优化器能做出返回结果集或中间结果集所花费时间的精确

UNIQUEIDENTIFIER列上的统计信息

UNIQUEIDENTIFIER列上的统计信息非常有意思,在它上面有一些很令人讨厌的行为.我们来看下. 问题重现(The repro) 为了向你展示我们刚抱怨的行为,我用下列简单的表定义创建了一个数据库,我在UNIQUEIDENTIFIER列上强制主键约束.这意味着SQL Server在后台会生成唯一聚集索引,聚集索引本身有一个统计信息对象来描述那列的数据分布情况.当然,数据分布是线性的,因为在UNIQUEIDENTIFIER列每个值本身都是唯一的. 1 -- Create a new tabl

javascript浮点值运算舍入误差

问题 在javascript中整数和浮点数都属于Number数据类型(简单数据类型中的一种),我们经常会发现在打印1.0这样的浮点数的结果是1而非1.0,这是由于保存浮点数的内存空间是保存整数值的两倍,所以ECMAScript会不失时机地将浮点数转换为整数. 上面这种情况虽然让强迫症患者有点不舒服,但是好歹也不是什么大错,接下来这种情况就很吓人了.例如我们在计算0.1加0.2时,它的输出结果不是0.3,而是0.3000000000000004.what the fuck?!第一次遇到这种情况的童

VARCHAR列上的索引

一年前,我写了在索引的导航结构里,SQL Server如何存储VARCHAR列.我们都知道,在SQL Server里索引(聚集索引,非聚集索引)的键列有最大900byte的大小限制. 假设现在你想捉弄下SQL Server,在VARCHAR(8000)的列上创建一个索引,并在索引键列上插入超900byte的值.想想,SQL Server会如何反应?不知道?我们来试验下.在下列代码里,我创建了有VARCHAR(8000)列的表,并在这列上创建非聚集索引. USE TempDb GO -- Crea

寻找数据表中一列相同并且存在另一列有不同值的记录

假如我有一张表  T  其中有两列 ,如下图所示: A B 1 3 1 3 2 5 2 4 3 7 3 7     其中,A列值为1的对应B列的值都为3,A列值为为2对应B列的值有两个,一个是5,一个是4,我们的目的就是列出  2  5,2 4 这两条记录. 第一种方法,巧妙的采用了max 和min函数,当我们使用A列分组后,如果 max(B)=min(B),那么B列的所有值肯定是相同的.反之则是我们需要寻找的记录.SQ如下: select * from T where T.A in (sele

列上加索引时事有条件

在列上加索引时事有条件的:1.经常被查询的列2.order by子句中使用的列3.是外键或者主键的列4.列是唯一的列5.两个或多个列经常同时出现在where子句中或者连接条件中 一般来说,应该在这些列上创建索引: 1在经常需要搜索的列上,可以加快搜索的速度: 2在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构: 3在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度: 4在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的: 5在经常需要排序的列上