0

I am looking to find the differences between two Lists of string arrays using the index 0 of the array as the primary key.

List<string[]> original = new List<string[]>();
List<string[]> web = new List<string[]>(); 

//define arrays for List 'original'
string[] original_a1 = new string[3]{"a","2","3"};
string[] original_a2 = new string[3]{"x","2","3"};
string[] original_a3 = new string[3]{"c","2","3"};

//define arrays for List 'web'
string[] web_a1 = new string[3]{"a","2","3"};
string[] web_a2 = new string[3]{"b","2","3"};
string[] web_a3 = new string[3]{"c","2","3"};

//populate Lists
original.Add(original_a1);
original.Add(original_a2);
original.Add(original_a3);

web.Add(web_a1);
web.Add(web_a2);
web.Add(web_a3);

My goal is to find what is in List 'original' but NOT in 'web' by using index 0 as the primary key
This is what I tried.

List<string> differences = new List<string>(); //differences go in here
string tempDiff = ""; // I use this to try and avoid duplicate entries but its not working

for(int i = 0; i < original.Count; i++){
 for(int j = 0; j< web.Count; j++){
     if(!(original[i][0].Equals(web[j][0]))){
      tempDiff = original[i][0];
     }
 }
 differences.Add(tempDiff);
}

OUTPUT:

foreach(string x in differences){
   Console.WriteLine("SIZE " + differences.Count);
   Console.WriteLine(x);
   ConSole.ReadLine();
}

SIZE 3

SIZE 3
x

SIZE 3

x

Why is it reporting the mismatch 3 times instead of once?

4 Answers 4

4

Using linq you can just go:

var differences = orignal.Except(web).ToList();

Reference here

This will give you the values that are in original, that don't exist in web

Sorry didn't read your question properly, to answer your question: You have a nested for-loop. So for each value of original (3) it will loop through all values of web (3), which is 9 loops total.

In 3 cases it doesn't match and therefore outputs 3 times.

Sign up to request clarification or add additional context in comments.

Comments

0

I think this is what you want. I use Linq to grab the primary keys, and then I use Except to do original - web. By the way, you can use == instead of Equals with strings in C# because C# does a value comparison as opposed to a reference comparison.

List<string[]> original = new List<string[]>
{
    new string[3] { "a", "2", "3" },
    new string[3] { "x", "2", "3" },
    new string[3] { "c", "2", "3" }
};
List<string[]> web = new List<string[]>
{
    new string[3] { "a", "2", "3" },
    new string[3] { "b", "2", "3" },
    new string[3] { "c", "2", "3" }
};

var originalPrimaryKeys = original.Select(o => o[0]);
var webPrimaryKeys = web.Select(o => o[0]);

List<string> differences = originalPrimaryKeys.Except(webPrimaryKeys).ToList();

Console.WriteLine("The number of differences is {0}", differences.Count);
foreach (string diff in differences)
{
    Console.WriteLine(diff);
}

And here it is without Linq:

var differences = new List<string>();

for (int i = 0; i < original.Count; i++)
{
    bool found = false;
    for (int j = 0; j < web.Count; j++)
    {
        if (original[i][0] == web[j][0])
        {
            found = true;
        }
    }

    if (!found)
    {
        differences.Add(original[i][0]);
    }
}

Comments

0

To answer your question: It is a nested for loop as stated in JanR's answer. This approach will make you reiterate to your web count 9 times, thus listing your mismatched key three times.

What could be a better way to do is this:

 //Check for originals not introduced in web.
        if(original.Count > web.Count)
        {

           for(int y = web.Count; y < original.Count; y++)

           {
              differences.Add(original[y][0]);
           }
        }
 //Check if Web has value, if not, everything else is done on the first for loop
         if(web.Count > 0)
         {
             for(int i = 0; i < original.Count; i++)
                {
                   if(!original[i][0].Equals(web[i][0]))
                      differences.Add(original[i][0]);
                }
         }

Also, the output is in a for loop, when you just need one result, the length of the mismatch. You can do that without a loop.

          Console.WriteLine("SIZE " + differences.Count);

This is, of course to make it kinda simpler if you're not used to using LINQ statements, but if you can do so with LINQ, then by all means, use LINQ as it's more efficient.

Comments

0

You can get the difference by using Except extension method like this:

var originalDic = original.ToDictionary(arr => arr.First());
var webDic = web.ToDictionary(arr => arr.First());
var differences =
    originalDic
    .Except(webDic, kvp => kvp.Key)
    .Select(kvp => kvp.Value)
    .ToList();

The trick here is to first convert your original and web lists into a Dictionary using the first element of each array as key and then perform Except.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.