[英]Get Single List Based on Join of Two Sub Lists
我有一個包含兩個List子屬性的Items列表,我需要獲取所有(唯一)值,這些值是這兩個子屬性被聯接(但僅在其父類中聯接)的結果。 下面是一個人為的示例:
類
public class Calendar
{
public List<int> Months { get; set; }
public List<int> Days { get; set; }
public int Id { get; set; }
public Calendar(int id)
{
Months = new List<int>();
Days = new List<int>();
this.Id = id;
}
}
我有一個Calendar對象列表,我需要從整個集合中獲取月/日組合的列表。 我設法通過將兩個SelectMany選項結合在一起來做到這一點:
var years = new List<Calendar>();
var cal2001 = new Calendar(1);
cal2001.Months = new List<int>() { 1, 2};
cal2001.Days = new List<int>() { 1, 6 };
years.Add(cal2001);
var cal2002 = new Calendar(2);
cal2002.Months = new List<int>() { 2, 4};
cal2002.Days = new List<int>() { 6, 15 };
years.Add(cal2002);
var items = (from M in years.SelectMany(Y => Y.Months, (Y, result) => new { Month = result, Id = Y.Id })
join D in years.SelectMany(Y => Y.Days, (Y, result) => new { Day = result, Id = Y.Id }) on M.Id equals D.Id
select new { Day = D.Day, Month = M.Month }).Distinct();
items.Dump(); //Dump items to output in Linqpad.
這給出了所需的輸出:
Day Month
1 1
6 1
1 2
6 2
15 2
6 4
15 4
因此,此方法有效,但是執行此查詢是否有更有效的方式?
嘗試這個:
years.SelectMany(y=> from d in y.Days
from m in y.Months
select new{d,m}) // cross join
.Distinct()
.Dump();
這給出了相同的輸出。
此外,您的要求真的是您想要實現的嗎? 如果同一年有多個日歷,它會給出時髦的結果。 例如,嘗試您的請求:
var years = new []{
new Calendar(2001){ Months = { 1 }, Days= { 2 }},
new Calendar(2001){ Months = { 3 }, Days= { 4 }},
};
=>這給出(2,1),(4,1),(2,3),(4,3)...這是預期的結果嗎? (如果是,我的請求無效)
如果實現IEqualityComparer
,則可以使用Distinct
清除重復項。 我介紹了一個名稱類DateEntry
,它對應於您擁有的匿名類型。 我還實現了IComparable
以便對結果進行排序。
public class DateEntryComparer : IEqualityComparer<DateEntry>
{
public bool Equals(DateEntry lhs, DateEntry rhs)
{
return lhs.Day == rhs.Day && lhs.Month == rhs.Month;
}
public int GetHashCode(DateEntry entry)
{
return entry.Day.GetHashCode() ^ entry.Month.GetHashCode();
}
}
public class DateEntry : IComparable<DateEntry>
{
public int Day {get;set;}
public int Month {get;set;}
public int CompareTo(DateEntry entry)
{
var result = Month.CompareTo(entry.Month);
if(result == 0)
{
result = Day.CompareTo(entry.Day);
}
return result;
}
}
public class Calendar
{
public List<int> Months { get; set; }
public List<int> Days { get; set; }
public int Year { get; set; }
public Calendar(int year)
{
Months = new List<int>();
Days = new List<int>();
Year = year;
}
public IEnumerable<DateEntry> GetDateEntries()
{
return from d in Days
from m in Months
select new DateEntry { Day = d, Month = m };
}
}
然后,您可以執行以下操作:
var items = years.SelectMany(y => y.GetDateEntries()).Distinct(new DateEntryComparer()).OrderBy(x => x);
items.Dump(); //Dump items to output in Linqpad.
輸出:
1 1
6 1
1 2
6 2
15 2
6 4
15 4
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.