我有以下列表,我想从列表Count
B
的属性A
以下是样本列表。请注意,我实际上使用的是Linq-To-Entities:
列出A
List<Leave> defaultLeaves = new List<Leave>()
{
new Leave{ Id = 1 , Count = 7},
new Leave{ Id = 2 , Count = 7},
new Leave{ Id = 3 , Count = 7},
new Leave{ Id = 4 , Count = 3}
};
列表B
List<Leave> usedLeaves = new List<Leave>()
{
new Leave{ Id = 1 , Count = 1},
new Leave{ Id = 2 , Count = 2}
};
我想通过使用相应A
B
的计数从列表Ids
中减去计数来使列表的输出成为这样
List<Leave> availableLeaves = new List<Leave>()
{
new Leave{ Id = 1 , Count = 6},
new Leave{ Id = 2 , Count = 5},
new Leave{ Id = 3 , Count = 7},
new Leave{ Id = 4 , Count = 3}
};
这可能是使用linq方法???
答案 0 :(得分:5)
IMO这是left outer join
的完美候选人:
var availableLeaves =
(from d in defaultLeaves
join u in usedLeaves on d.Id equals u.Id into match
from u in match.DefaultIfEmpty()
select new Leave
{
Id = d.Id,
Count = d.Count - (u != null ? u.Count : 0)
}).ToList();
答案 1 :(得分:4)
您可以使用linq
var availableLeaves = defaultLeaves.Select(x => new Leave()
{
Id = x.Id,
Count = x.Count - usedLeaves.FirstOrDefault(u => u.Id == x.Id)?.Count ?? 0
}).ToList();
主要部分是这一行
Count = x.Count - usedLeaves.FirstOrDefault(u => u.Id == x.Id)?.Count ?? 0
usedLeaves.FirstOrDefault(u => u.Id == x.Id)
获取具有相同ID的Leave
。如果它不存在则为null
,因此整个usedLeaves.FirstOrDefault(u => u.Id == x.Id)?.Count
为null
,这会导致减去零,这不会影响计数。
答案 2 :(得分:2)
出于性能原因,我会将usedLeaves
变成字典:
var dic = usedLeaves.ToDictionary(l => l.Id, l => l.Count);
然后我会用它来生成结果列表:
availableLeaves = defaultLeaves.Select(l =>
new Leave {Id = l.Id, Count = l.Count - dic[l.Id]})
.ToList();
当然,如果第一个列表的Id
未包含在第二个列表中,您可能需要添加一些错误处理:
availableLeaves = defaultLeaves.Select(l =>
{
int count;
if (!dic.TryGetValue(l.Id, out count))
count = 0;
return new Leave {Id = l.Id, Count = l.Count - count});
}).ToList();
对于较大的列表,建议将第二个转换为字典,因为Id
以FirstOrDefault()
方式访问对象要比使用usedLeaves.AsEnumerable().ToDictionary()
每次单独查看它们要快得多。
更新:没有考虑到我们在谈论EF。所以我不确定哪种方式更好。如果您想立即加载所有这些叶子并将它们保留在客户端,则必须致电FirstOrDefault()
正如我所说,我没有足够的经验来决定这是否比使用连续的.rocket-move-one {
animation-timing-function: linear;
}
电话寻找每一个更好。
答案 3 :(得分:1)
这是一个班轮:
var leaves = defaultLeaves.GroupJoin(usedLeaves, dl => dl.Id, ul => ul.Id,
(dl, ulList) => new Leave { Id = dl.Id, Count = dl.Count - (ulList.Any() ? ulList.FirstOrDefault().Count : 0) });
正如Ivan Stoev所说,这是一个简单的LEFT JOIN。可以执行此操作的扩展方法是GroupJoin()