c# - 计算 DataTable 中的同比变化
问题描述
我在DataTable
下面模拟了:
+----+------+-------------+--------+
| ID | YEAR | PERSON_NAME | AMOUNT |
+----+------+-------------+--------+
| 1 | 2004 | BARBARA | 500 |
| 2 | 2004 | BOB | 100 |
| 3 | 2004 | JANE | 30 |
| 4 | 2004 | JOHN | 200 |
| 5 | 2005 | BARBARA | 505 |
| 6 | 2005 | BOB | 150 |
| 7 | 2005 | JANE | 15 |
| 8 | 2005 | JOHN | 215 |
| 10 | 2006 | BARBARA | 523 |
| 11 | 2006 | BOB | 185 |
| 12 | 2006 | JANE | 25 |
| 13 | 2006 | JOHN | 207 |
+----+------+-------------+--------+
我正在尝试添加一个新列,以跟踪每个人的金额的逐年变化:
+----+------+-------------+--------+-------+
| ID | YEAR | PERSON_NAME | AMOUNT | Y-O-Y |
+----+------+-------------+--------+-------+
| 1 | 2004 | BARBARA | 500 | |
| 2 | 2004 | BOB | 100 | |
| 3 | 2004 | JANE | 30 | |
| 4 | 2004 | JOHN | 200 | |
| 5 | 2005 | BARBARA | 505 | 5 |
| 6 | 2005 | BOB | 150 | 50 |
| 7 | 2005 | JANE | 15 | -15 |
| 8 | 2005 | JOHN | 215 | 15 |
| 10 | 2006 | BARBARA | 523 | 18 |
| 11 | 2006 | BOB | 185 | 35 |
| 12 | 2006 | JANE | 25 | 10 |
| 13 | 2006 | JOHN | 207 | -8 |
+----+------+-------------+--------+-------+
我通过在某些ON
条件下将表连接到自身,在 SQL 中轻松实现了这一点,并试图模仿 c# 的相同逻辑,DataTable
并让它以某种复杂的方式工作。我想知道是否有使用 LINQ 或DataView
s 的更清洁的方法,或者只是一种紧凑的算法来达到相同的效果。谢谢!
解决方案
尝试以下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
DataTable dt = new DataTable();
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("YEAR", typeof(int));
dt.Columns.Add("PERSON_NAME", typeof(string));
dt.Columns.Add("AMOUNT", typeof(int));
dt.Rows.Add(new object[] { 1, 2004, "BARBARA", 500 });
dt.Rows.Add(new object[] { 2, 2004, "BOB", 100 });
dt.Rows.Add(new object[] { 3, 2004, "JANE", 30 });
dt.Rows.Add(new object[] { 4, 2004, "JOHN", 200 });
dt.Rows.Add(new object[] { 5, 2005, "BARBARA", 505 });
dt.Rows.Add(new object[] { 6, 2005, "BOB", 150 });
dt.Rows.Add(new object[] { 7, 2005, "JANE", 15 });
dt.Rows.Add(new object[] { 8, 2005, "JOHN", 215 });
dt.Rows.Add(new object[] { 10, 2006, "BARBARA", 523 });
dt.Rows.Add(new object[] { 11, 2006, "BOB", 185 });
dt.Rows.Add(new object[] { 12, 2006, "JANE", 25 });
dt.Rows.Add(new object[] { 13, 2006, "JOHN", 207 });
dt.Columns.Add("Y-O-Y", typeof(int));
List<List<DataRow>> groups = dt.AsEnumerable()
.OrderBy(x => x.Field<int>("YEAR"))
.GroupBy(x => x.Field<string>("PERSON_NAME"))
.Select(x => x.ToList())
.ToList();
foreach (List<DataRow> person in groups)
{
for (int i = 1; i < person.Count(); i++)
{
person[i]["Y-O-Y"] = person[i].Field<int>("AMOUNT") - person[i - 1].Field<int>("AMOUNT");
//or
//person[i]["Y-O-Y"] = (int)person[i]["AMOUNT"] - (int)person[i - 1]["AMOUNT"];
}
}
}
}
}
推荐阅读
- python - 使用交换距离选择排序后恢复原始数组
- javascript - 来自 asyncStorage、Apollo、React Native 的 creatHttpLink
- html - 如何在谷歌浏览器中删除页面html底部的iframe水平滚动条?
- mongodb - Mongo查询分组并使用group by计算平均值
- r - 数据表 R || 汇总数据表列表中的特定列
- python - 每当输入有一些触发时,如何使破折号间隔从 0 开始
- swiftui - HStack 返回“VStack”视图
- ffmpeg - ffmpeg:考虑增加probesize错误,但它永远不会满足
- java - 将 JSON 映射到 POJO 以进行处理 - 未识别的字段未标记为可忽略
- java - 在java中只需要获取主机名而不是FQDN