【问题标题】:compare three arrays and show difference [duplicate]比较三个数组并显示差异[重复]
【发布时间】:2012-12-19 13:20:42
【问题描述】:

可能重复:
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. 单个列表中的元素将是唯一的。
3. 我打算尽可能地跳过循环并在 LINQ/Generics 中寻找 .NET 3.5 / 4.0 的新功能,我可以在这里应用它们!

对于那些投反对票或结束这个问题的人,请解释一下?

【问题讨论】:

  • 对它们进行排序并循环遍历它们。
  • 你有没有尝试过用一系列嵌套循环解决这个问题的所谓天真的方法?如果是这样,性能是否不可接受?
  • 对不起,两个人可以做的事情可以做三个或更多。
  • @Pratik 我的赞成票(不是反对票)是因为您根本没有尝试过任何事情。 LINQ 方法非常有据可查,并在 Stack Overflow 上进行了介绍。展示你迄今为止尝试过的东西;不要只是今天来到这里要求解决方案。

标签: c# .net arrays string comparison


【解决方案1】:

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

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

【讨论】:

  • 我宁愿推荐在这种情况下使用集合而不是普通数组,因为集合已经内置了函数来帮助加速这种类型的过程。
【解决方案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 链接。

【讨论】:

    【解决方案3】:

    您可以使用 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   ║
    ╚══════════════════════════════════════╝
    

    【讨论】:

      【解决方案4】:

      我会在 O(4N) 或其他时间做这样的事情,但也许有人知道更快的方法。

      private void PrintDiff()
      {
              public Dictionary<string, Model> dictionary = new Dictionary<string, Model>();
      
              foreach (var entry in Array1)
              {
                  dictionary.Add(entry, (new Model()).Add(entry, "Array1"));
              }
              foreach (var entry in Array2)
              {
                  if (!dictionary.ContainsValue(entry))
                       dictionary.Add(entry, (new Model()).Add(entry, "Array2"));
              }
              foreach (var entry in Array3)
              {
                  if (!dictionary.ContainsValue(entry))
                       dictionary.Add(entry, (new Model()).Add(entry, "Array3"));
              }
      
      
              //now print 
              foreach (var model in dictionary)
              {
                  model.ToString();
              }
          }
      
      public class Model
      {
      
          public Model()
          {
              Dictionary = new Dictionary<string, string>();
          }
      
          private Dictionary<string, string> Dictionary
          {
              get;
              set;
          }
      
          public bool ContainsEntry(string entry)
          {
              return Dictionary.ContainsValue(entry);
          }
      
          public void Add(string entry, string arrayName)
          {
              Dictionary.Add(arrayName, entry);
          }
      
          public override string ToString()
          {
              return "FORMATED AS YOU WANT THEM";
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-11-08
        • 1970-01-01
        • 1970-01-01
        • 2015-08-10
        • 2017-05-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多