score:1

Accepted answer

You can get rid of the inner loop using System.Linq. Also simplify code by using foreach instead of for for main loop:

ConcurrentDictionary<string, string> compareDictionary = new ConcurrentDictionary<string, string>();

foreach (var element in list1)
{
   var item1Name= element.Name.ToString();
   var item1Id= element.ID.ToString();
   // If this element has already one correspondence, TryAdd will fail anyway
   if(compareDictionary.ContainsKey(item1Id)) continue; 

   var found = list2.FirstOrDefault(item => item1Name.Contains(item.item2Name.ToLower()));
   if(found != null)
   {
          compareDictionary.TryAdd(item1Id, item.item2Id);
   }
}

Depending on your elements naming, you also could need to make item1Name lower case. Your code will in fact find this correspondence:

Parentwithlittlechild --> LittleChild

but not this:

ParentWithLittleChild --> LittleChild

because "LittleChild" would be lower cased, and String.Contains works case sensitively by default. You could also use IndexOf method with StringComparison.OrdinalIgnoreCase, like this:

var found = list2.FirstOrDefault(item => item1Name.IndexOf(item.item2Name, StringComparison.OrdinalIgnoreCase) >= 0);

Final consideration: element.Name is probably already of type string, unless your Item1.Name property is some funny type. If so, element.Name.ToString() is convertible in just element.Name.

score:1

Couple of code snippets to find the matches and add the ids of the two objects in a ConcurrentDictionary<string, string>.

So we have:

var dict = new ConcurrentDictionary<string, string>();

First

list1.ForEach(x =>
{
    list2.Where(y => y.Item2Name.IndexOf(x.Name, StringComparison.CurrentCultureIgnoreCase) >= 0)
    .ToList().ForEach(y => dict.TryAdd(x.ID, y.Item2Id));
});

Second

(from x in list1
    from y in list2
    where x.Name.IndexOf(y.Item2Name, StringComparison.CurrentCultureIgnoreCase) >= 0
    select (x, y)).ToList().ForEach(item => dict.TryAdd(item.x.ID, item.y.Item2Id));

Side Note

  • If both Item1.Name and Item2.Item2Name properties are of string type, then no need to use ToString() function like in var item1Name= list1[i].Name.ToString(); line.

  • If both Item1.ID and Item2.Item2Id properties are of int type, then the proper type of both Key and Value pairs of the dictionary is the int type. So:

var dict = new ConcurrentDictionary<int, int>();

Related Articles