比较三个数组并显示差异

时间:2012-12-19 13:20:43

标签: c# .net arrays string comparison

  

可能重复:
  Compare two Lists for differences

我有以下数组

string[] arr1 = { 1155717, 5184305, 2531291, 1676341, 1916805 ... } 
string[] arr2 = { 1155717, 1440230, 2531291, 8178626, 1916805 ... }
string[] arr3 = { 1155717, 5184305, 4025514, 1676341, ... }

数组是数百万&也可以包含字符。 我想在csv

中创建这样的报告
diff.csv

arr1,arr2,arr3
1155717,1155717,1155717
5184305,--N/A--,5184305
--N/A--,1440230,--N/A--
--N/A--,--N/A--,4025514
1676341,--N/A--,1676341
--N/A--,8178626,--N/A--
1916805,1916805,--N/A--

我想在每个&中申请循环比较不会是那么好的方法。任何想法?
我错过的几件事:
1.订单无关紧要。
2.单个列表中的元素将是唯一的 我打算尽可能地跳过循环。在LINQ / Generics中寻找.NET 3.5 / 4.0的新功能,我可以在这里申请!

对于那些投票否定或关闭此问题,请解释一下?

3 个答案:

答案 0 :(得分:2)

我用int类型的数组做了一个小例子,但这可以应用于字符串

        int[] arr1 = { 1155717, 5184305, 2531291, 1676341, 1916805 } ;
        int[] arr2 = { 1155717, 1440230, 2531291, 8178626, 1916805 };
        int[] arr3 = { 1155717, 5184305, 4025514, 1676341 };

        foreach (int i in arr1)
        {
            Console.Write(i + "  ");
            foreach (int b in arr2)
            {
                if (i == b)
                    Console.Write(b + "  ");

            }
            foreach (int c in arr3)
            {
                if (i == c)
                    Console.Write(c + "  ");
            }
            Console.WriteLine();
        }
        Console.ReadLine();

唯一的问题是你在循环中使用循环,所以如果你的数组很大,那么你的表现就会受到影响。这只是一个让你思考的简单想法。

答案 1 :(得分:2)

您可以使用此Linq查询和string.Join

string[][] all = new[] { arr1, arr2, arr3 };
int maxLength = all.Max(arr => arr.Length);
string separator = ",";
string defaultValue = "N/A";

var csvFields = all.Select(arr => Enumerable.Range(0, maxLength)
                   .Select(i => arr.Length <= i ? defaultValue : arr[i]));
string csv = string.Join(Environment.NewLine, 
                        csvFields.Select(f => string.Join(separator, f)));
File.WriteAllText(path, csv);  

Demo

我将所有数组放在锯齿状数组中。然后我使用int范围作为起点(样本中为0-4,因为最大的数组有5个元素)。然后我从每个数组中取5个元素,如果数组小于该索引,则取默认值"N/A"

最后一步是使用string.Join将每个数组的所有部分与您的分隔符(",")和每个Environment.NewLine相关联。

答案 2 :(得分:1)

您可以将linq用于GroupJoin:

string[] arr1 = { "1155717", "5184305", "2531291", "1676341", "1916805" };
string[] arr2 = { "1155717", "1440230", "2531291", "8178626", "1916805" };
string[] arr3 = { "1155717", "5184305", "4025514", "1676341" };

var allPossibleTerms = arr1.Union(arr2).Union(arr3);

allPossibleTerms
    .GroupJoin(arr1, all => all, a1 => a1, (all, a1) => new { Number = all, A1 = a1 })
    .SelectMany(joined => joined.A1.DefaultIfEmpty(), (collection, result) => new { collection.Number, A1 = result})
    .GroupJoin(arr2, joined => joined.Number, a2 => a2, (collection, a2) => new { Number = collection.Number, A1 = collection.A1, A2 = a2 })
    .SelectMany(joined => joined.A2.DefaultIfEmpty(), (collection, result) => new { collection.Number, A1 = collection.A1, A2 = result})
    .GroupJoin(arr3, joined => joined.Number, a3 => a3, (collection, a3) => new { Number = collection.Number, A1 = collection.A1, A2 = collection.A2, A3 = a3 })
    .SelectMany(joined => joined.A3.DefaultIfEmpty(), (collection, result) => new { collection.Number, A1 = collection.A1, A2 = collection.A2, A3 = result});;

基本上,这会创建所有术语的主列表,并在每个阵列的连接时加入。

╔══════════════════════════════════════╗
║ Number   A1       A2       A3        ║
╠══════════════════════════════════════╣
║ 1155717  1155717  1155717  1155717   ║
║ 5184305  5184305  -------  5184305   ║
║ 2531291  2531291  2531291  -------   ║
║ 1676341  1676341  -------  1676341   ║
║ 1916805  1916805  1916805  -------   ║
║ 1440230  -------  1440230  -------   ║
║ 8178626  -------  8178626  -------   ║
║ 4025514  -------  -------  4025514   ║
╚══════════════════════════════════════╝