Skip to main content

C# Merge Dictionaries

15 Aug 2020 - Cody Merritt Anhorn

While working on my Game client conversion, which is why I have not posted many articles for a while, I found a need to merge two dictionaries into a single dictionary. Its not a real complicated process, but I all the examples I found would alway use the item from the first dictionary or would throw exceptions on a duplicate. To get around these two scenarios I created the MergeLayoutControlOptions method below, it takes in a list of Dictionary typed objects and merges them with the last grouped value taking priority in the new Dictionary.

To give a real world scenario I am using a class that extends the framework Dictionary. I like this pattern since it allows me to create explicit wrappers around a Dictionary, but still get the functionality of the framework provided Dictionary. Using this pattern also allows me to add functionality to the way a Dictionary works without having to create extensions methods, that make it hard to test. Another added benefit is that I also get a typed object for my options instead of a generic dictionary that I have to know I have extension methods to work with it.

Example of Generated Source

You can checkout this fiddle Merge Dictionaries to play around with the code that is provided below.

Example output:

Key: key1 | Value: value1
Key: key2 | Value: value2-from2
Key: key3 | Value: value3
Key: key4 | Value: value4-from2
Key: key5 | Value: value5
using System;
using System.Linq;
using System.Collections.Generic;
					
public class Program
{
	public static void Main()
	{
		var options1 = new GuiControlOptionsModel(
			new Dictionary<string, object>
			{
				{"key1", "value1"},
				{"key2", "value2"},
				{"key3", "value3"},
				{"key4", "value4"},
				{"key5", "value5"},
			}
		);
		var options2 = new GuiControlOptionsModel(
			new Dictionary<string, object>
			{
				{"key2", "value2-from2"},
				{"key4", "value4-from2"},
			}
		);

		var mergedOptions = MergeLayoutControlOptions(
			options1,
			options2
		);

		foreach (var option in mergedOptions)
		{
			System.Console.WriteLine(
				$"Key: {option.Key} | Value: {option.Value}"
			);
		}
	}

    
    /// <summary>
    /// Will merge the provided options into a single options.
    /// Will use the last option value as priority in new Option Model.
    /// </summary>
    /// <param name="options">Options to merge values from.</param>
    /// <returns>A consolidated Options Model of all passed in Option Key/Value</returns>
	private static GuiControlOptionsModel MergeLayoutControlOptions(
		params IGuiControlOptions[] options
	)
	{
		return new GuiControlOptionsModel(
			options.SelectMany(x => x)
				.GroupBy(d => d.Key)
				.ToDictionary(x => x.Key, y => y.Last().Value)
		);
	}

	public interface IGuiControlOptions
		: IDictionary<string, object>
	{

	}

	public class GuiControlOptionsModel
		: Dictionary<string, object>,
		IGuiControlOptions
	{
		public GuiControlOptionsModel(
			IDictionary<string, object> dictionary
		) : base(dictionary ?? new Dictionary<string, object>())
		{
		}
	}
}

Categories: blog

Tags: .NET Core C#


Cody Merritt Anhorn
Email: cody.anhorn@hotmail.com