c#linq合并2本词典

c#linq合并2本词典,c#,linq,C#,Linq,我有两本字典项具有公共属性内部级别 我想结合这两个字典,其中键是唯一的,我想能够在这两个字典上指定级别 差不多 dictionary 1 = all items that level < 10 dictionary 2 = all items level < 20 combine dictionary 2 with 1 (where Value.Level < 10) if the Key is unique and the Value.Level < 20 字典1=级

我有两本字典<代码>项具有公共属性内部级别

我想结合这两个字典,其中键是唯一的,我想能够在这两个字典上指定级别

差不多

dictionary 1 = all items that level < 10 dictionary 2 = all items level < 20 combine dictionary 2 with 1 (where Value.Level < 10) if the Key is unique and the Value.Level < 20 字典1=级别<10的所有项目 字典2=所有项目级别<20 将字典2与1合并(其中Value.Level<10) 如果键是唯一的且值.Level<20 我可以很容易地用foreach循环实现这一点。我还可以通过多个linq查询来实现这一点。 然而,我似乎不知道如何进行这一个linq查询

编辑-根据您的请求John这里是foreach的代码

Dictionary<string, Dictionary<string, Item>> itemDictionary = new Dictionary<string, Dictionary<string, Item>>();

Dictionary<string, Item> items = new Dictionary<string,Item>();

            if (itemDictionary.ContainsKey(comboBox.Text))
            {
                foreach (KeyValuePair<string, Item> kvp in itemDictionary[comboBox.Text])
                {
                    if (!items.ContainsKey(kvp.Key) && kvp.Value.Level <= int.Parse(textBox.Text))
                        items.Add(kvp.Key, kvp.Value);
                }
            }

            if (itemDictionary.ContainsKey(comboBox1.Text))
            {
                foreach (KeyValuePair<string, Spell> kvp in itemDictionary[comboBox1.Text])
                {
                    if (!items.ContainsKey(kvp.Key) && kvp.Value.Level <= int.Parse(textBox1.Text))
                        items.Add(kvp.Key, kvp.Value);
                }
            }
            var query = from s in items
                        orderby s.Value.Level
                        select s;

            foreach (var i in query)
               listBox.Items.Add(string.Format("{0} {1}", i.Value.Level, i.Key));
Dictionary itemDictionary=new Dictionary();
字典项=新字典();
if(itemDictionary.ContainsKey(comboBox.Text))
{
foreach(itemDictionary[comboBox.Text]中的KeyValuePair kvp)
{

如果(!items.ContainsKey(kvp.Key)&&kvp.Value.Level如果您可以在foreach循环中轻松地执行您想要的操作,那么您已经编写了代码。这告诉我,foreach代码可能比复杂的LINQ查询更可读、更易于维护


这听起来是保留foreach循环代码的最佳情况。LINQ可能较新,但并不总是意味着它更好。

如果我不理解您的意思,请更正:您希望两个字典中都有记录。无论如何,我的示例可以根据您的特殊需要进行调整

Dictionary<string, string> d1 = new Dictionary<string, string>(), d2 = new Dictionary<string, string>();
        var merged = d1
            .Join(d2, d1key => d1key.Key, d2key => d2key.Key,
                (i1, i2) => new { Key = i1.Key, Value1 = i1.Value, Value2 = i2.Value })
            .ToDictionary(t => t.Key);
Dictionary d1=newdictionary(),d2=newdictionary();
var=d1
.Join(d2,d1key=>d1key.Key,d2key=>d2key.Key,
(i1,i2)=>new{Key=i1.Key,Value1=i1.Value,Value2=i2.Value})
.ToDictionary(t=>t.Key);
“合并”将仅包含两个词典中存在的项,并且将能够获取每个项的数据,如“合并[“键”].Value1”和“合并[“键”].Value2” 例如,我使用了匿名类型(new{}),因此您只能在同一个方法中或在绑定中访问Value1和Value2,因为它们是动态的。
在其他情况下,您应该创建一个类型来存储组合结果。

好的,该代码明确了您要完成的任务。因此,最终结果应该是一个字典,由两个字典中满足指定级别的项组成。如果两个字典中都存在一个项,则首选第一个字典中的项。While在一个Linq查询中完成这一点是可能的,您最终可能会重复一些工作

var itemsOne = new[] {
    new { Name = "A", Level = 1 },
    new { Name = "B", Level = 2 },
    new { Name = "C", Level = 3 },
    new { Name = "D", Level = 4 }
}.ToDictionary(i => i.Name, i => i);

var itemsTwo = new[] {
    new { Name = "C", Level = 10 },
    new { Name = "D", Level = 20 },
    new { Name = "E", Level = 30 },
    new { Name = "F", Level = 40 }
}.ToDictionary(i => i.Name, i => i);

var itemsOneLevel = 3;
var itemsTwoLevel = 30;

var validFromItemsOne = (from item in itemsOne
                         where item.Value.Level <= itemsOneLevel
                         select item).ToDictionary(i => i.Key, i => i.Value);

var validFromItemsTwo = from item in itemsTwo
                        where item.Value.Level <= itemsTwoLevel
                            && !validFromItemsOne.ContainsKey(item.Key)
                        select item;

var items = validFromItemsOne
    .Concat(validFromItemsTwo)
    .ToDictionary(i => i.Key, i => i.Value);
var itemsOne=new[]{
新的{Name=“A”,级别=1},
新的{Name=“B”,级别=2},
新的{Name=“C”,级别=3},
新建{Name=“D”,级别=4}
}.ToDictionary(i=>i.Name,i=>i);
var itemsTwo=new[]{
新的{Name=“C”,级别=10},
新的{Name=“D”,级别=20},
新的{Name=“E”,级别=30},
新建{Name=“F”,级别=40}
}.ToDictionary(i=>i.Name,i=>i);
var itemsOneLevel=3;
var itemsTwoLevel=30;
var validFromItemsOne=(来自itemsOne中的项
其中item.Value.leveli.Key,i=>i.Value);
var validFromItemsTwo=来自itemsTwo中的项目
其中item.Value.leveli.Key,i=>i.Value);

我认为这是一个适用于此场景的扩展

public static class Extensions
{
    public static IDictionary<TKey, TValue> Combine<TKey, TValue>(
        this IDictionary<TKey, TValue> firstSet,
        IDictionary<TKey, TValue> secondSet,
        Func<KeyValuePair<TKey, TValue>, bool> firstFilter,
        Func<KeyValuePair<TKey, TValue>, bool> secondFilter)
    {
        return firstSet
        .Where(firstFilter)
        .Concat(secondSet.Where(secondFilter))
        .GroupBy(d => d.Key)
        .ToDictionary(d => d.Key, d => d.First().Value);
    }
}
公共静态类扩展
{
公共静态索引组合(
这是本词典的第一集,
IDictionary secondSet,
Func firstFilter,
Func(第二个过滤器)
{
返回第一集
.其中(第一个过滤器)
.Concat(secondSet.Where(secondFilter))
.GroupBy(d=>d.Key)
.ToDictionary(d=>d.Key,d=>d.First().Value);
}
}
用法:

var itemsOne = new[] {
    new { Name = "A", Level = 1 },
    new { Name = "B", Level = 2 },
    new { Name = "C", Level = 3 },
    new { Name = "D", Level = 4 }
}.ToDictionary(i => i.Name, i => i);

var itemsTwo = new[] {
    new { Name = "C", Level = 10 },
    new { Name = "D", Level = 20 },
    new { Name = "E", Level = 30 },
    new { Name = "F", Level = 40 }
}.ToDictionary(i => i.Name, i => i);

itemsOne
.Combine(itemsTwo,
    kvp => kvp.Value.Level <= 3,
    kvp => kvp.Value.Level <= 30)
    .ToDictionary(d => d.Key, d=> d.Value.Level)
var itemsOne=new[]{
新的{Name=“A”,级别=1},
新的{Name=“B”,级别=2},
新的{Name=“C”,级别=3},
新建{Name=“D”,级别=4}
}.ToDictionary(i=>i.Name,i=>i);
var itemsTwo=new[]{
新的{Name=“C”,级别=10},
新的{Name=“D”,级别=20},
新的{Name=“E”,级别=30},
新建{Name=“F”,级别=40}
}.ToDictionary(i=>i.Name,i=>i);
项目名称
.合并(项目2,
kvp=>kvp.Value.Level kvp.Value.Level d.Key,d=>d.Value.Level)
结果:

A 1 B 2 C 3 D 20 E 30 A 1 B 2 C3 D 20 E 30
因此,您想要的结果是一个字典,其中包含字典1中的所有项以及字典2中的所有项。当您说“合并”时,字典1中不存在谁的密钥你的意思是将字典2中的元素插入到新字典中,还是将字典2中的元素插入字典1中?@scmcart,听起来更像是1的子集和2的子集。你说的“在键唯一的情况下合并这两个字典”是什么意思?如果两个字典中都有相同的键,您希望发生什么?如果您可以使用foreach向我们展示您当前的代码,我们可能会帮助您…Anthony是对的,我正在寻找两个字典的子集+1我讨厌调试
LINQ
。它有它的时刻,但在某些情况下,如果我更好地理解LINQ,foreach会更好en可读性成为一个有争议的问题。我的目的是更好地掌握linq,而不是产生答案。d1和d2将它们结合起来,使d3=唯一的项。如果d1和d2都有一个值,且级别满足条件,则只添加d1值,忽略d2值。