C#如何合并两个字典与用户定义的类型,不包括重复

时间:2017-03-20 07:52:19

标签: c# linq list dictionary merge

class DataContainer
{
    public Dictionary<int, byte[]> bockedData { get; set; }
    ...
    ...
    ..
}

我有

List<DataContainer> orginalReq;
List<DataContainer> gapReq;

我正在尝试在bockedData中合并那些没有重复键的那两个。 LINQ可以实现吗?请帮助如何合并这两个列表。

编辑: 针对这种情况的控制台代码:

 static void Main(string[] args)
        {
            List<DataContainer> fromFist = new List<DataContainer>();
            fromFist = GetFirstreq();
            List<DataContainer> fromGap = new List<DataContainer>();
            fromGap = GetGap();
            //To Do Merge fromFist and fromGap with out dups



        }

        static List <DataContainer> GetFirstreq()
        {
            List<DataContainer> firstReq = new List<DataContainer>();
            Dictionary<int, byte[]> dict1 = new Dictionary<int, byte[]>();
            dict1.Add(1, new byte[] { 0x00, 0x01 });
            dict1.Add(2, new byte[] { 0x00, 0x01 });
            dict1.Add(3, new byte[] { 0x00, 0x01 });

            Dictionary<int, byte[]> dict2 = new Dictionary<int, byte[]>();
            dict2.Add(7, new byte[] { 0x00, 0x01 });
            dict2.Add(8, new byte[] { 0x00, 0x01 });
            dict2.Add(9, new byte[] { 0x00, 0x01 });
            firstReq.Add(new DataContainer() { BlockedData = dict1 });
            firstReq.Add(new DataContainer() { BlockedData = dict2 });
            return firstReq;
        }

        static List<DataContainer> GetGap()
        {
            //this can have dups
            List<DataContainer> firstReq = new List<DataContainer>();
            Dictionary<int, byte[]> dict1 = new Dictionary<int, byte[]>();
            dict1.Add(1, new byte[] { 0x00, 0x01 });
            dict1.Add(2, new byte[] { 0x00, 0x01 });
            dict1.Add(3, new byte[] { 0x00, 0x01 });

            //nedded data
            Dictionary<int, byte[]> dict2 = new Dictionary<int, byte[]>();
            dict2.Add(4, new byte[] { 0x00, 0x01 });
            dict2.Add(5, new byte[] { 0x00, 0x01 });
            dict2.Add(6, new byte[] { 0x00, 0x01 });
            firstReq.Add(new DataContainer() { BlockedData = dict1 });
            firstReq.Add(new DataContainer() { BlockedData = dict2 });
            return firstReq;
        }
    }

    class DataContainer
    {
        public Dictionary<int, byte[]> BlockedData { get; set; }
    }

我希望现在这很清楚。

结果可能会像:

List<DataContainer> firstReq = new List<DataContainer>();
            Dictionary<int, byte[]> dict1 = new Dictionary<int, byte[]>();
            dict1.Add(1, new byte[] { 0x00, 0x01 });
            dict1.Add(2, new byte[] { 0x00, 0x01 });
            dict1.Add(3, new byte[] { 0x00, 0x01 });

            Dictionary<int, byte[]> dict2 = new Dictionary<int, byte[]>();
            dict2.Add(4, new byte[] { 0x00, 0x01 });
            dict2.Add(5, new byte[] { 0x00, 0x01 });
            dict2.Add(6, new byte[] { 0x00, 0x01 });

            Dictionary<int, byte[]> dict3 = new Dictionary<int, byte[]>();
            dict2.Add(7, new byte[] { 0x00, 0x01 });
            dict2.Add(8, new byte[] { 0x00, 0x01 });
            dict2.Add(9, new byte[] { 0x00, 0x01 });


            firstReq.Add(new DataContainer() { BlockedData = dict1 });
            firstReq.Add(new DataContainer() { BlockedData = dict2 });
            firstReq.Add(new DataContainer() { BlockedData = dict3 });

我可以将那些Dicts合并为:

var gap = fromGap.SelectMany(o => o.BlockedData).ToDictionary(o => o.Key, o => o.Value);
var orginal = fromFirst.SelectMany(o => o.BlockedData).ToDictionary(o => o.Key, o => o.Value);
var final = orginal.Concat(gap.Where(kvp => !orginal.ContainsKey(kvp.Key))).ToDictionary(x => x.Key, x => x.Value);

1 个答案:

答案 0 :(得分:0)

您没有很好地指定合并

  • 是否要将DataContainers的两个列表合并到一个DataContainers列表中,其中包含原始列表中的所有DataContainers列表?
  • 或者您想将所有bockedData的所有DataContainers合并到一个字典中?当然,只有当所有bockedData中的所有DataContainers的密钥都是唯一的时,这才有效。

第一个很简单:

IEnumerable<DataContainer> result = originalReq.Concat(gapReq);

或者如果你想要一个清单:

List<DataContainer> result = originalReq.Concat(gapReq).ToList();

第二种方法,将所有内容放入一个大字典中,要求您将两个列表中所有KeyValuePairs的所有bockedData中的所有DataContainers作为一个序列,并将此序列转换为一个字典,其中每个KeyValuePair的键为键,每个KeyValuePair的值为值。

在婴儿步骤中:

IEnumerable<Dictionary<int, byte[]>> allDictionaries = originalReq
    .Concat(gapReq)
    .Select(datacontainer => datacontainer.bockedData);
IEnumerable<KeyValuePair<int, byte[]>> allBockedDataRecords = allDictionaries
    .SelectMany(dictionary => dictionary.Cast<IEnumerable<KeyValuePair<int, byte[]>>);
Dictionary<int, byte[]> result = allBockedDataRecords.ToDictionary(
    record => record.Key,   // from every record take the Key as dictionary key
    record => record.Value, // from every record take value as dictionary value

或者在一个linq声明中:

 Dictionary<int, byte[]> result = originalReq.Concat(gapReq)
    .SelectMany(dataContainer => dataContainer.bockedData)
    .ToDictionary(
        record => record.Key,
        record => record.Value);