我想Lambda我的代码但是卡住了。
基本上: 如果数组对象包含4个具有自己的年份规范和id的成员。然而,该数组可以包含更多具有相同和不同Id和年份的成员(但从不相同的Id和同年)。
会员阵列:
array[0]: Id 1 Year 2010
array[1]: Id 2 Year 2010
array[2]: Id 1 Year 2008
array[3]: Id 1 Year 2009
首先 - 我想删除所有具有2010年特定ID的阵列成员,如果他们在阵列中还有另一年(相同的ID,不同的年份)。所以在这种情况下我想删除[0]但不删除其他成员。
其次 - 我想在2010年之后保持2010年之后的最新一年,即2009年的Id 1,这意味着我也想删除[2]。 (这些年来作为字符串,这就是为什么我将它们转换为int以便在下面的代码中进行比较)
下面是我的代码,其for循环有效,我需要专家Lambda帮助以避免循环:
var x = Member.Length;
for (int i = 0; i < x; i++)
{
var y = Member[i].id;
for (int j = i; j < x; j++)
{
var z = Member[j].id;
if (i != j)
{
if (y == z)
{
if (Member[i].year == "2010")
{
Member = Member.Where(w => w != Member[i]).ToArray();
i--;
j--;
x--;
break;
}
var tempI = Convert.ToInt32(Member[i].year);
var tempJ = Convert.ToInt32(Member[j].year);
if (tempI > tempJ)
{
Member = Member.Where(w => w != Member[j]).ToArray();
i--;
j--;
x--;
break;
}
}
}
}
}
答案 0 :(得分:1)
我同意这个要求并没有多大意义,但这就是我解释的方式
var Member = new[]
{
new { id = 1, year = "2010" },
new { id = 2, year = "2010" } ,
new { id = 1, year = "2008" } ,
new { id = 1, year = "2009" }
};
var results = from item in Member.Select(x => new { x.id, Year = Convert.ToInt32(x.year), item = x })
group item by item.id into sameItems
let order = sameItems.OrderByDescending(x => x.Year)
let first = order.ElementAtOrDefault(0)
let second = order.ElementAtOrDefault(1)
select first.Year == 2010 && second != null ? second.item : first.item;
foreach (var item in results)
{
System.Console.WriteLine($"id:{item.id},year:{item.year}");
}
答案 1 :(得分:0)
我倾向于避免使用LINQ来更改我正在查询的底层集合。 下面的代码将为每个成员选择最多两个最近的条目。
var result = new List<MemberClass>();
var groups = Member.OrderBy(m => m.Id).ThenByDescending(m => m.Year).GroupBy(m => m.Id).ToList();
groups.ForEach(c => result.AddRange(c.Take(2)));
使用result
代替原始数组。
我不知道性能是否是您的考虑因素。随着收藏的增长,上面的代码可能会变慢。
答案 2 :(得分:0)
您的描述和要求不相容,但这是一种解释:
public class Member
{
public int Id { get; set; }
public string Year { get; set; }
}
var items = (new List<Member>() {
new Member() { Id=1, Year="2010" },
new Member() { Id=2, Year="2010" },
new Member() { Id=1, Year="2008" },
new Member() { Id=1, Year="2009" }
}).ToArray();
// Group everythnig by year, then only keep the highest id
var firstFiltered = items
.GroupBy(
x => x.Year,
x => x.Id,
(year, ids) => new Member()
{
Id = ids.Last(),
Year = year
});
var secondFiltered = firstFiltered
// Only keep years before 2010
.Where(x => String.Compare(x.Year, "2010") == -1)
// Then order by Id then Year
.OrderBy(x => x.Id)
.ThenBy(x => x.Year)
// And only keep the last/most recent year
.GroupBy(
x => x.Id,
x => x.Year,
(id, years) => new Member()
{
Id = id,
Year = years.Last()
});