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为字符串类型日期
public class DataTableCompute
{
/// <summary>
/// 对DataTabella行上的列根据运算式计算
/// </summary>
/// <param name="dicDecimal">数值类型表达式键值对</param>
/// <param name="dicTime">时间类型表达式键值对</param>
/// <param name="row">DataTable表上的行</param>
public static void ComputeColumns(Dictionary<string, string> dicDecimal, Dictionary<string, string> dicTime, DataRow row)
{
if (dicDecimal != null && dicDecimal.Count > )
{
foreach (KeyValuePair<string, string> kvp in dicDecimal)
{
GetExpressionByType(row, kvp, "decimal");
}
}
if (dicTime != null && dicTime.Count > )
{
foreach (KeyValuePair<string, string> kvp in dicTime)
{
GetExpressionByType(row, kvp, "time");
}
} } private static void GetExpressionByType(DataRow row, KeyValuePair<string, string> kvp, string type)
{
string result = kvp.Key;
string expression = kvp.Value;
string[] cols = expression.Split(new char[] { '(', ')', '+', '-', '*', '/', '\\' },StringSplitOptions.RemoveEmptyEntries);
for (int m = ; m < cols.Length; m++)
{
if (type == "time")
{
DateTime time = DateTime.Now;
if (cols[m].ToLower() != "now")
{
DateTimeFormatInfo dtfi = new CultureInfo("zh-CN", true).DateTimeFormat;
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))
{
time = DateTime.Now;
}
}
cols[m] = (time.Year * + time.Month).ToString();
}
else
{
double d = ;
if (double.TryParse(row[cols[m]].ToString(), out d))
{
d = Math.Round(d, );
}
cols[m] = d.ToString();
}
}
StringBuilder newExpression = new StringBuilder();
int n = ;
for (int k = ; k < expression.Length; k++)
{
char c = expression[k];
int intAsciiCode = (int)c;
if (intAsciiCode >= && intAsciiCode <= )
{
newExpression.Append(c.ToString() + " ");
continue;
}
if (c == 'F' || c == 'n')
{
newExpression.Append(cols[n] + " ");
n++;
}
}
string str = newExpression.ToString();
row[result] = CalculateResult(str);
}
private static double CalculateResult(string expre)
{
List<string> temp = getColuExpression(expre);
try
{
while (temp.Count > )
{
for (int i = ; i < temp.Count; i++)
{
double resultTemp = ;
if (temp[i] == "+")
resultTemp = Convert.ToDouble(temp[i - ]) + Convert.ToDouble(temp[i - ]);
else if (temp[i] == "-")
resultTemp = Convert.ToDouble(temp[i - ]) - Convert.ToDouble(temp[i - ]);
else if (temp[i] == "*")
resultTemp = Convert.ToDouble(temp[i - ]) * Convert.ToDouble(temp[i - ]);
else if (temp[i] == "/")
resultTemp = Convert.ToDouble(temp[i - ]) / Convert.ToDouble(temp[i - ]);
else
continue;
temp[i - ] = resultTemp.ToString();
temp.RemoveAt(i);
temp.RemoveAt(i - );
break;
}
}
}
catch (Exception ex)//计算表达式的值错误,导致无法运算
{
temp.Clear();
temp.Add("");
}
return Convert.ToDouble(temp[]);
}
private static List<string> getColuExpression(string exp)
{
System.Text.ASCIIEncoding asc = new System.Text.ASCIIEncoding();
Stack st = new Stack();
string[] temp = exp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
List<string> value = new List<string>(); for (int i = ; i < temp.Length; i++)
{
int num = (int)asc.GetBytes(temp[i])[];
if (num < && num > )
{
if (st.Count > )
{
string operatorStr = st.Peek().ToString();
if (temp[i] == "*" || temp[i] == "/")
{
if (temp[i + ] == "(")
{
st.Push(temp[i]); continue;
}
else
{
if (operatorStr == "(")
{
st.Push(temp[i]);
continue;
}
else if (operatorStr == "*" || operatorStr == "/")
{
value.Add(st.Pop().ToString());
st.Push(temp[i]);
continue;
}
else
{
st.Push(temp[i]);
continue;
}
}
}
else if (temp[i] == "+" || temp[i] == "-")
{
if (operatorStr == "(")
{
st.Push(temp[i]);
continue;
}
else
{
value.Add(st.Pop().ToString());
if (st.Count > && st.Peek().ToString() != "(")
{
value.Add(st.Pop().ToString());
}
st.Push(temp[i]);
continue;
}
}
else if (temp[i] == "(")
{
st.Push(temp[i]);
continue;
}
else
{
if (i + == temp.Length)
{
value.Add(st.Pop().ToString());
st.Pop();
while (st.Count > )
value.Add(st.Pop().ToString());
break;
}
else
{
value.Add(st.Pop().ToString());
st.Pop();
continue;
}
}
}
else
{
st.Push(temp[i]);
continue;
}
}
else if (i + == temp.Length)
{
value.Add(temp[i]);
value.Add(st.Pop().ToString());
while (st.Count > )
value.Add(st.Pop().ToString());
break;
}
else
{
value.Add(temp[i]);
continue;
}
}
return value;
}
}
DataTable列计算类
DataTable列上多值运算的更多相关文章
- 【Excel】SUMIF 或用 筛选器 实现挑选含有某些字段的值,然后把这些值所对应的后面某列上的值相加
Background: 挑选含有某些字段的值,然后把这些值所对应的后面某列上的值相加.比如挑选下表中,所有带有“MX104”这个字段的值,然后把它的后面total那一列的值相加. Solution: ...
- 获取DataTable某一列的所有值
/// <summary> /// 获取某一列的所有值 /// </summary> /// <typeparam name="T">列数据类型 ...
- VARCHAR列上的索引
一年前,我写了在索引的导航结构里,SQL Server如何存储VARCHAR列.我们都知道,在SQL Server里索引(聚集索引,非聚集索引)的键列有最大900byte的大小限制. 假设现在你想捉弄 ...
- SQL Server如何在变长列上存储索引
这篇文章我想谈下SQL Server如何在变长列上存储索引.首先我们创建一个包含变长列的表,在上面定义主键,即在上面定义了聚集索引,然后往里面插入80000条记录: -- Create a new t ...
- 深入理解计算机系统(2.2)---布尔代数以及C语言上的位运算
布尔代数上的位运算 布尔代数是一个数学知识体系,它在0和1的二进制值上演化而来的. 我们不需要去彻底的了解这个知识体系,但是里面定义了几种二进制的运算,却是我们在平时的编程过程当中也会遇到的.这四种运 ...
- UNIQUEIDENTIFIER列上的统计信息
UNIQUEIDENTIFIER列上的统计信息非常有意思,在它上面有一些很令人讨厌的行为.我们来看下. 问题重现(The repro) 为了向你展示我们刚抱怨的行为,我用下列简单的表定义创建了一个数据 ...
- Oracle中Clob类型处理解析:ORA-01461:仅可以插入LONG列的LONG值赋值
感谢原作者:破剑冰-Oracle中Clob类型处理解析 上一篇分析:ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值 最近为Clob字段在插入数据时发现当字符的字节数(一个半角字符一 ...
- 索引列上的统计 <第一篇>
一.索引在查询优化中的角色 SQL Server的查询优化器是基于开销的优化器.它通过确认选择性.数据的唯一性以及过滤数据(通过WHERE或JOIN子句)所使用的列来决定最佳的数据访问机制.统计与索引 ...
- 关于 Oracle外键列上是否需要索引问题?
外键列上缺少索引会带来两个问题,限制并发性.影响性能.而这两个问题中的任意一个都可能会造成严重性能问题. 无论是Oracle的官方文档,还是在Tom的书中都说明了两种情况下可以忽略外键上的索引.其 ...
随机推荐
- Kakfa分布式集群搭建
本位以最新版本kafka_2.11-0.10.1.0版本讲述分布式kafka集群环境的搭建过程.服务器列表: 172.31.10.1 172.31.10.2 172.31.10.3 1.下载kafka ...
- .net mvc Bundle 问题解决方案
使用.net MVC4 开发Web项目时,可以利用"Bundle"对Css.JS文件进行压缩打包,一方面可以减少数据加载的次数,另一方面可以减少数据传输量,但在实际使用中却遇到了问 ...
- U3D rootMotion
Body Transform The Body Transform is the mass center of the character. It is used in Mecanim's retar ...
- Linux 读书笔记 一
一.Linux 简介 实验介绍 本节主要介绍 Linux 的历史,Linux 与 Windows 的区别等入门知识.如果你已经有过充分的了解,可以跳过本节,直接进入下一个实验. 一.Linux 为何物 ...
- 微信小程序全选,微信小程序checkbox,微信小程序购物车
微信小程序,这里实现微信小程序checkbox,有需要此功能的朋友可以参考下. 摘要: 加减商品数量,汇总价格,全选与全不选 设计思路: 一.从网络上传入以下Json数据格式的数组 1.标题titl ...
- 集DDD,TDD,SOLID,MVVM,DI,EF,Angularjs等于一身的.NET(C#)开源可扩展电商系统–Virto Commerce
今天一大早来看到园友分享的福利<分享一个前后端分离方案源码-前端angularjs+requirejs+dhtmlx 后端asp.net webapi>,我也来分享一个吧.以下内容由笔者写 ...
- angular_routerJS_学习
//这几天看了angularjs和backbone,大看了解了knockout和emberjs,刚刚上网看到了一个angular的router的demo,现在顺便记下来 <!--- DEMO_I ...
- [JQuery EasyUI系列]简介
一.jQuery EasyUI是一个基于jQuery的框架,继承了各种用户界面插件. 二.jQuery EasyUI框架提供了创建网页所需的一切,可以轻松建立站点. easyui是一个基于jQuery ...
- Java 读取文件到字符串
Java的io操作比较复杂 package cn.outofmemory.util; import java.io.BufferedReader; import java.io.FileInputSt ...
- SQLHelper---赵晓虎(简洁,全面)
public static class SQLHelper { //获取连接字符串,,首先添加对configuration的引用 private static string connStr = Con ...