Try something along these lines
Dictionary<int, string[]> failedDict = new()
{
{ 0, new string[] { "A", "B", "C" } },
{ 1, new string[] { "D", "E", "F" } }
};
Dictionary<int, string[]> batchDict = new()
{
{ 3, new string[] { "J", "K", "L" } },
{ 2, new string[] { "G", "H", "I" } }
};
Dictionary<int, string[]> batchDict2 = new()
{
{ 4, new string[] { "M", "N", "O" } },
{ 5, new string[] { "P", "Q", "R" } }
};
List<(string name, IDictionary<int, string[]> failedProducts)> failedList = new()
{
("Widget",failedDict)
};
List<(string name, IDictionary<int, string[]> batch)> batchList = new()
{
("Item", batchDict),
("Widget",batchDict2)
};
foreach(var b in batchList)
{
bool isMatched=false;
foreach(var (name, failedProducts) in failedList)
{
if(b.name == name)
{
var kvPairs = b.batch.ToList();
kvPairs.ForEach(kv => failedProducts.Add(kv.Key, kv.Value));
isMatched = true;
break;
}
}
if(!isMatched)
{
failedList.Add(b);
}
}
foreach(var (name, failedProducts) in failedList)
{
Console.WriteLine(name);
foreach(var kvp in failedProducts)
{
Console.WriteLine($"{kvp.Key} {string.Join(',',kvp.Value)}");
}
}