簡體   English   中英

有效的數據結構來容納員工的活動?

[英]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類型混淆,您可能要為其命名一些不同的名稱。也許是JobJobTask東西?)

員工有一系列任務:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM