查找2个字符串数组列表中的差异

时间:2016-03-07 04:55:43

标签: c# arrays

我希望找到两个字符串数组列表之间的差异,使用数组的索引0作为主键。

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);

我的目标是找到List&#39; original&#39;中的内容。但不是在&#39; web&#39;通过使用索引0作为主键
这就是我的尝试。

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);
}

输出:

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

SIZE 3

SIZE 3
x

SIZE 3

x

为什么报告不匹配3次而不是一次?

4 个答案:

答案 0 :(得分:4)

使用linq你可以去:

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

参考here

这将为您提供original中不存在的值web

抱歉没有正确阅读您的问题,回答您的问题: 你有一个嵌套的for循环。因此对于原始(3)的每个值,它将循环遍历web(3)的所有值,总共9个循环。

在3种情况下,它不匹配,因此输出3次。

答案 1 :(得分:0)

我认为这就是你想要的。我使用Linq来获取主键,然后使用Except来执行original - web。顺便说一句,您可以在C#中使用==代替Equals字符串,因为C#执行值比较而不是参考比较。

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);
}

这里没有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]);
    }
}

答案 2 :(得分:0)

回答你的问题:这是一个嵌套的for循环,如JanR的回答所述。这种方法会让你重复你的网络计数9次,从而列出你不匹配的密钥三次。

可能更好的方法是:

 //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]);
                }
         }

此外,当您只需要一个结果时,输出处于for循环中,即不匹配的长度。你可以在没有循环的情况下做到这一点。

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

当然,如果您不习惯使用LINQ语句,这样做会更简单,但如果您可以使用LINQ,那么无论如何都要使用LINQ,因为它更有效。

答案 3 :(得分:0)

您可以使用Except扩展方法获得差异:

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();

这里的技巧是首先使用每个数组的第一个元素作为键将原始列表和网络列表转换为Dictionary,然后执行Except