有没有办法重写下面的GetTransformedCollection
方法,以便它使用Linq语句而不是表达式?我目前正试图绕过“一个带有语句体的lambda表达式无法转换为表达式树”错误。
public class Obj1
{
public int Id { get; set; }
public string[] Names { get; set; }
public string[] Tags { get; set; }
}
public class EntCollections
{
private List<Obj1> _results;
[SetUp]
public void SetUp()
{
_results = new List<Obj1>
{
new Obj1 {Id = 1, Names = new[] {"n1"}, Tags = new[] {"abc", "def"}},
new Obj1 {Id = 2, Names = new[] {"n2", "n3"}, Tags = new[] {"ghi"}},
new Obj1 {Id = 3, Names = new[] {"n1", "n3"}, Tags = new[] {"def", "xyz"}}
};
}
private static Dictionary<string, List<string>>
GetTransformedCollection(IEnumerable<Obj1> results)
{
var list = new Dictionary<string, List<string>>();
foreach (var result in results)
{
foreach (var id in result.Names)
{
if (list.ContainsKey(id))
{
list[id].AddRange(result.Tags);
}
else
{
list.Add(id, result.Tags.ToList());
}
}
}
return list;
}
[Test]
public void Test()
{
var list = GetTransformedCollection(_results);
Assert.That(list["n1"], Is.EquivalentTo(new [] { "abc", "def", "def", "xyz" }));
Assert.That(list["n2"], Is.EquivalentTo(new [] { "ghi" }));
Assert.That(list["n3"], Is.EquivalentTo(new [] { "ghi", "def", "xyz" }));
}
P.s我不太担心结果类型是一个字典,这只是将它表达为返回类型的简单方式。
答案 0 :(得分:7)
我个人会使用ILookup
,只要您拥有Dictionary<T1, List<T2>>
,这是一个不错的选择,并使用ToLookup()
构建:
// Flatten the objects (lazily) to create a sequence of valid name/tag pairs
var pairs = from result in results
from name in result.Names
from tag in result.Tags
select new { name, tag };
// Build a lookup from name to all tags with that name
var lookup = pairs.ToLookup(pair => pair.name, pair => pair.tag);
答案 1 :(得分:2)
想法是查找结果字典的所有键,然后从Obj1
的原始序列中找到相应的值
var distinctNames = results.SelectMany(val => val.Names).Distinct();
return distinctNames
.ToDictionary(name => name,
name => results
.Where(res => res.Names.Contains(name))
.SelectMany(res => res.Tags)
.ToList());