[英]Efficient data structure to hold employee's activities?
我的目录中有n个excel文件,该文件存储一个月中每天的活动。 它们具有三列:日期,活动和类别。 我不需要类别。
我想基本上阅读n个excel文件并输出一个word文档,该文档有效地按日期将每个员工的所有活动按日期排序,例如:
第1天到第5天:
第一天:
员工#1:
-任务a
-任务b
-任务c
员工#2:
-任务a
-任务b
-任务c
...
第2天:...
...
...
第7天到第11天:
……
我想知道我可以使用哪种数据结构来有效地保存此信息,以便可以轻松编写所需的文档。 现在,我正在使用一个字符串数组来保存每个excel行,并将它们全部存储在一个列表中,然后将其存储在每个员工的字典中,关键是每个员工的用户名。
虽然我认为这些数据结构本身是有效的,但对于我的主要目标(即打印每位员工每天订购的数据)来说,它们并不是太友好,所以关键也许应该是日期。
回顾一下:当前使用的数据结构:
Dictionary<string,List<string[]>> dictActividades = new Dictionary<string,List<string[]>>();
每个员工的excel文件中的所有行都存储在一个列表中。 我真的不需要字典功能,因为我可以按顺序读回所有内容。 我在读取员工的excel文件时可能会立即进行打印,但是我必须一次读取n个excel文件(尽管n很小)
思考?
编辑:这是我目前拥有的:
string directorioActividades = @"\\mar-fp01\mar_tecnologia$\Coordinacion de Apoyo a Usuarios\Informes\" +
fechaInicio.Year.ToString() + "\\" + fechaInicio.Year.ToString() + "-" +
fechaInicio.Month.ToString().PadLeft(2, '0');
string[] archivos = Directory.GetFiles(directorioActividades, "*.xlsx");
Dictionary<string,List<string[]>> dictActividades = new Dictionary<string,List<string[]>>();
for (int j = 0; j < archivos.Length; j++)
{
List<string[]> actividades = new List<string[]>();
string nombreArchivo = Path.GetFileNameWithoutExtension(archivos[j]);
String excelConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;" +
"Data Source=" + archivos[j] + ";" +
"Extended Properties=Excel 8.0; ";
using (OleDbConnection con = new OleDbConnection(excelConnectionString))
{
OleDbCommand command = new OleDbCommand("Select * From [Actividades$]", con);
con.Open();
OleDbDataReader dr = command.ExecuteReader();
int cantidadcolumnas = dr.FieldCount;
string tipodatos = null;
string[] filaDatos = new string[cantidadcolumnas];
while (dr.Read())
{
for (int k = 0; k < cantidadcolumnas; k++)
{
tipodatos = dr.GetFieldType(k).ToString();
if (tipodatos == "System.Int32")
{
filaDatos[k] = dr.GetInt32(k).ToString();
}
if (tipodatos == "System.String")
{
filaDatos[k] = dr.GetString(k);
}
if (tipodatos == "System.DateTime")
{
filaDatos[k] = dr.GetDateTime(k).ToShortDateString();
}
}
actividades.Add(filaDatos);
}//while dr.read
}
dictActividades.Add(nombreArchivo, actividades);
}//for archivos
虽然此代码很短,并且使用的是我能想到的最少的数据结构,但是打印非常困难,因为关键是员工的用户名而不是日期,并且该代码应按日期按格式打印每个员工的每项活动,例如格式上面发布
如果您不按语义组织数据并将逻辑包含在模型中,则对这些数据执行逻辑将非常不直观。 考虑报价:
“智能数据结构和哑代码比其他方法要好得多。”
-埃里克·雷蒙德(Eric Raymond),大教堂和集市
您所描述的结构包含您需要的所有信息:
第一天:
员工#1:
-任务a
-任务b
-任务c
因此,您从Task
对象开始:
class Task
{
// fields which describe a Task
}
(为避免与内置Task
类型混淆,您可能要为其命名一些不同的名称。也许是Job
或JobTask
东西?)
员工有一系列任务:
class Employee
{
public IList<Task> Tasks { get; set; }
}
一天有一组员工:
class Day
{
public IList<Employee> Employees { get; set; }
}
(如果此域超出了仅此一项操作的范围,那么您甚至可能以不同的方式命名事物。从技术上讲,它们是“雇员”,例如它们是“ EmployeeTaskLogs”。域的大小和复杂性将指导任何此类命名。但绝对要对最明智的名称进行一些思考,这就是本练习的全部重点。)
然后,您的顶级消费代码将只有Days的集合:
var days = new List<Day>();
您可以通过创建自定义集合类型来进一步优化业务逻辑。 例如,如果您想利用“天字典”:
class DayDictionary<T> : IDictionary<T> where T : Day
{
// implement IDictionary<T> here
}
例如,您可以在其中包含诸如确保任何给定集合具有正好5天对象之类的逻辑。
一旦定义了模型结构,使用它们就变得微不足道了,它们的语义也变得显而易见。
我建议像这样一个简单的课程
class EmployeeActivity
{
public string Employee { get; set; }
public DateTime Date { get; set; }
public string Activity { get; set; }
}
没有特殊的数据结构-仅List<EmployeeActivity>
。 填充后,您可以使用LINQ执行所需的排序/分组。
想象一下,而不是您的字典,您填充我的建议
var empoyeeActivies = new List<EmployeeActivity>();
// Iterate excel files like in your code and populate the list
现在,您可以使用以下方法将其转换为示例中显示的方式
var result = employeeActivities
.GroupBy(a => a.Date, (date, dateActivities) => new
{
Date = date,
DateActivities = dateActivities
.GroupBy(a => a.EmployeeName, (employeeName, employeeActivities) => new
{
EmployeeName = employeeName,
Activities = empoyeeActivities.OrderBy(a => a.Activity)
})
.OrderBy(a => a.EmployeeName)
})
.OrderBy(a => a.Date);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.