簡體   English   中英

我如何在 linq c# 中透視對象列表並創建新列表?

[英]how do i pivot list of object and create new list in linq c#?

我有一份員工每天工作時間數據的列表。 我想透視日期和小時數據,並創建一個新的對象列表,其中包含員工姓名,以及以相應小時數為值的一系列天數。

我的清單看起來像

List<EmployeeHour> employeeHours = new List<EmployeeHour>
{
new EmployeeHour{Id = 1, EmployeeName = "Emp1", Day = 1, Hours = 6},
new EmployeeHour{Id = 1, EmployeeName = "Emp1", Day = 2, Hours = 8},
new EmployeeHour{Id = 2, EmployeeName = "Emp2", Day = 1, Hours = 6},
new EmployeeHour{Id = 2, EmployeeName = "Emp2", Day = 2, Hours = 8}
};

我想創建新的對象列表,其中的時間類似於

new {
   Id = 1,
   EmplyeeName = Emp1,
   Day1 = 6,
   Day2 = 8
},
new {
   Id = 2,
   EmplyeeName = Emp2,
   Day1 = 6,
   Day2 = 8
}

我就是這樣做的。 有更好的解決方案嗎?

  dynamic d = new
                    {
                        Employee = group.FirstOrDefault().EmployeeName,
                        Day1 = group.FirstOrDefault(g => g.DayNumber == 1)?.HoursPerDay,
                        Day2 = group.FirstOrDefault(g => g.DayNumber == 2)?.HoursPerDay,
                        Day3 = group.FirstOrDefault(g => g.DayNumber == 3)?.HoursPerDay,
                        Day4 = group.FirstOrDefault(g => g.DayNumber == 4)?.HoursPerDay,
                        Day5 = group.FirstOrDefault(g => g.DayNumber == 5)?.HoursPerDay,
                        Day6 = group.FirstOrDefault(g => g.DayNumber == 6)?.HoursPerDay,
                        Day7 = group.FirstOrDefault(g => g.DayNumber == 7)?.HoursPerDay
                    };
list.Add(d);

使用字典。

C# 是一種強類型語言,因此類屬性的可變性是有限的。 似乎更適合您的是Dictionary<string, object>

var dictionaries = employeeHours.Select(x => new {x.Id, x.EmployeeName})
    .Distinct()
    .Select(x => new Dictionary<string, object>()
    {
        {"Id", x.Id},
        {"EmployeeName", x.EmployeeName}
    })
    .ToList();

foreach (var dict in dictionaries)
{
    var id = (int)dict["Id"];
    foreach (var dh in employeeHours.Where(x => x.Id == id))
    {
        if (!dict.ContainsKey("Day" + dh.Day))
        {
            dict["Day" + dh.Day] = dh.Hours;
        }
    }
}

這段代碼會給你一個可變長度的字典,當它使用 JSON 轉換時,它應該為你提供數據表中所需的數據結構。

如果您希望結果是靜態類型的匿名(或定義的類)對象,則需要執行類似於您正在執行的操作。

我將使用從每個組轉換而來的增強型字典類型,以便更輕松地提取值:

//***
// Enhanced Dictionary that returns default(TValue) for missing values
//***
public class NullDictionary<TKey, TValue> : Dictionary<TKey, TValue> {
    public NullDictionary(IDictionary<TKey, TValue> d) : base() {
        foreach (var kvp in d)
            Add(kvp.Key, kvp.Value);
    }
    public NullDictionary() : base() { }

    public new TValue this[TKey key]
    {
        get
        {
            TryGetValue(key, out var val);
            return val;
        }
        set
        {
            base[key] = value;
        }
    }
}

使用擴展方法使創建變得容易:

public static class DictExt {
    public static NullDictionary<TKey, TValue> ToNullDictionary<T, TKey, TValue>(this IEnumerable<T> src, Func<T, TKey> keyFn, Func<T, TValue> valFn) {
        var nd = new NullDictionary<TKey, TValue>();
        foreach (var s in src)
            nd.Add(keyFn(s), valFn(s));
        return nd;
    }
}

現在您可以使用GroupBy透視數據並提取匿名對象:

var ans = employeeHours.GroupBy(eh => new { eh.Id, eh.EmployeeName }, eh => new { Day = $"Day{eh.Day}", eh.Hours })
                         .Select(pg => {
                             var pd = pg.ToNullDictionary(p => p.Day, p => (int?)p.Hours);
                             return new {
                                pg.Key.Id,
                                pg.Key.EmployeeName,
                                Day1 = pd["Day1"],
                                Day2 = pd["Day2"],
                                Day3 = pd["Day3"],
                                Day4 = pd["Day4"],
                                Day5 = pd["Day5"],
                                Day6 = pd["Day6"],
                                Day7 = pd["Day7"],
                            };
                         })
                         .ToList();

還可以為每個列表成員使用更動態的對象,例如DataTableDictionaryExpandoObject ,甚至可以在運行時創建匿名對象,盡管在大多數情況下這是有問題的價值,因為您可以' t 輕松訪問其字段。 但是,如果您不知道Day值是如何可能的,並且想要處理不同的數字,則必須使用這些值之一或用某種類型的集合代替 day 字段(例如數組、列表或字典) )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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