C# 压平字典<;int,List<;对象>&燃气轮机;
我有一个字典,它有一个表示一年的整数键,还有一个值是objectC# 压平字典<;int,List<;对象>&燃气轮机;,c#,linq,dictionary,key-value,C#,Linq,Dictionary,Key Value,我有一个字典,它有一个表示一年的整数键,还有一个值是objectChannel的列表。我需要将数据展平并从中创建一个新对象 目前,我的代码如下所示: Dictionary<int, List<Channel>> myDictionary; foreach(var x in myDictionary) { var result = (from a in x.Value from b in anotherList
Channel
的列表。我需要将数据展平并从中创建一个新对象
目前,我的代码如下所示:
Dictionary<int, List<Channel>> myDictionary;
foreach(var x in myDictionary)
{
var result = (from a in x.Value
from b in anotherList
where a.ChannelId == b.ChannelId
select new NewObject
{
NewObjectYear = x.Key,
NewObjectName = a.First().ChannelName,
}).ToList();
list.AddRange(result);
}
但是有了这个,我无法直接获得键。使用类似于flatten.Select(x=>x.Key)
的方法肯定是不正确的。因此,我试图找到其他方式来平复,这将有利于我的场景,但失败了。我还考虑创建一个类,其中包含年份和列表,但我不知道如何创建。
请帮我做这个
另外,是否还有其他不需要创建新类的方法?在我看来,您只是尝试进行筛选,不需要加入:
var anotherListIDs = new HashSet<int>(anotherList.Select(c => c.ChannelId));
foreach (var x in myDictionary)
{
list.AddRange(x.Value
.Where(c => anotherListIDs.Contains(c.ChannelId))
.Select(c => new NewObject
{
NewObjectYear = x.Key,
NewObjectName = c.First().ChannelName,
}));
}
var-anotherListIDs=newhashset(anotherList.Select(c=>c.ChannelId));
foreach(myDictionary中的变量x)
{
list.AddRange(x.Value
.Where(c=>anotherListIDs.Contains(c.ChannelId))
.选择(c=>NewObject
{
NewObjectYear=x.键,
NewObjectName=c.First().ChannelName,
}));
}
您确实意识到,如果特定字典元素中列表的第二个元素具有匹配的channelId,那么您将返回此列表的第一个元素,不是吗
var otherList = new OtherItem[]
{
new OtherItem() {ChannelId = 1, ...}
}
var dictionary = new Dictionary<int, List<Channel>[]
{
{ 10, // Key
new List<Channel>() // Value
{
new Channel() {ChannelId = 100, Name = "100"},
new Channel() {ChannelId = 1, Name = "1"},
},
};
这将调用其他ExtractNewobjects:
public static IEnumerable<NewObject> ExtractNewObjects(this Dictionary<int, List<Channel>> dictionary,
IEnumerable<int> otherChannelIds)
{
var channelIdsSet = new HashSet<int>(otherChannelIds));
// duplicate channelIds will be removed automatically
foreach (KeyValuePair<int, List<Channel>> keyValuePair in dictionary)
{
// is any ChannelId in the list also in otherChannelIdsSet?
// every keyValuePair.Value is a List<Channel>
// every Channel has a ChannelId
// channelId found if any of these ChannelIds in in the HashSet
bool channelIdFound = keyValuePair.Value
.Any(channel => otherChannelIdsSet.Contains(channel.ChannelId);
if (channelIdFound)
{
yield return new NewObject()
{
NewObjectYear = keyValuePair.Key,
NewObjectName = keyValuePair.Value
.Select(channel => channel.ChannelName)
.FirstOrDefault(),
};
}
}
}
公共静态IEnumerable ExtractNewObjects(此字典,
IEnumerable OtherChannelId)
{
var channelIdsSet=newhashset(otherchannelid));
//重复的ChannelID将自动删除
foreach(字典中的KeyValuePair KeyValuePair)
{
//列表中的任何ChannelId是否也在OtherChannelID集中?
//每个keyValuePair.Value都是一个列表
//每个频道都有一个ChannelId
//如果HashSet中存在这些channelId中的任何一个,则找到channelId
bool channelIdFound=keyValuePair.Value
.Any(channel=>otherChannelIdsSet.Contains(channel.ChannelId);
if(channelIdFound)
{
返回新的NewObject()
{
NewObjectYear=keyValuePair.Key,
NewObjectName=keyValuePair.Value
.选择(通道=>channel.ChannelName)
.FirstOrDefault(),
};
}
}
}
用法:
IEnumerable<OtherItem> otherList = ...
Dictionary<int, List<Channel>> dictionary = ...
IEnumerable<Newobject> extractedNewObjects = dictionary.ExtractNewObjects(otherList);
var someNewObjects = extractedNewObjects
.Take(5) // here we see the benefit from the yield return
.ToList();
IEnumerable otherList=。。。
字典=。。。
IEnumerable extractedNewObjects=字典。ExtractNewObjects(其他列表);
var someNewObjects=extractedNewObjects
.Take(5)//这里我们看到了收益回报的好处
.ToList();
我们可以看到四项效率改进:
- 使用
HashSet
可以快速查找ChannelId
是否位于OtherList
- 在
哈希集中找到匹配的Channelid
后,使用Any()
停止枚举列表
- 使用
yield return
可以使您在字典中枚举的元素不会超过实际使用的元素数
- 创建
NewObjectName
时,使用Select
和FirstOrDefault
可以防止列表为空时出现异常
为什么你的意思是你不能直接拿到钥匙?你所做的看起来很好。“…绝对不是正确的方法”那么什么是正确的方法呢?我不明白。在x.Value中的中,a
是频道,而不是列表。确实你有a.ChannelId
,但是你以后怎么能使用a.First()
?OPs问题包含a.First().ChannelName
,其中a
是一个频道。因此,频道实现了IEnumerable
,而不是你所认为的IEnumerable
。从现在起,恐怕它就注定要失败。
public static IEnumerable<NewObject> ExtractNewObjects(this Dictionary<int, List<Channel>> dictionary,
IEnumerable<int> otherChannelIds)
{
var channelIdsSet = new HashSet<int>(otherChannelIds));
// duplicate channelIds will be removed automatically
foreach (KeyValuePair<int, List<Channel>> keyValuePair in dictionary)
{
// is any ChannelId in the list also in otherChannelIdsSet?
// every keyValuePair.Value is a List<Channel>
// every Channel has a ChannelId
// channelId found if any of these ChannelIds in in the HashSet
bool channelIdFound = keyValuePair.Value
.Any(channel => otherChannelIdsSet.Contains(channel.ChannelId);
if (channelIdFound)
{
yield return new NewObject()
{
NewObjectYear = keyValuePair.Key,
NewObjectName = keyValuePair.Value
.Select(channel => channel.ChannelName)
.FirstOrDefault(),
};
}
}
}
IEnumerable<OtherItem> otherList = ...
Dictionary<int, List<Channel>> dictionary = ...
IEnumerable<Newobject> extractedNewObjects = dictionary.ExtractNewObjects(otherList);
var someNewObjects = extractedNewObjects
.Take(5) // here we see the benefit from the yield return
.ToList();