-1

重複の可能性:
2つのリストを比較して違いを確認する

私は次の配列のセットを持っています

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.1つのリスト内の要素は一意になります。
3.ループを可能な限りスキップし、ここで適用できるLINQ/Genericsの.NET3.5/4.0の新機能を探す予定です。

反対票を投じたり、この質問を閉じたりする場合は、そのように説明してください。

4

4 に答える 4

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

唯一の問題は、ループ内でループを使用していることです。そのため、配列が大きい場合、パフォーマンスが影響を受けます。これは、考えさせるための単純なアイデアです。

于 2012-12-19T13:42:39.977 に答える
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);  

デモ

すべての配列をジャグ配列に入れました。次に、int範囲を開始点として使用します(最大の配列には5つの要素があるため、サンプルでは0〜4です)。次に、各配列から 5 つの要素を取得し"N/A"、配列がそのインデックスよりも小さい場合の既定値を取得します。

最後の段階ではstring.Join、各配列のすべての部分を区切り文字 ( ",")でリンクし、すべてのをでリンクしますEnvironment.NewLine

于 2012-12-19T13:50:53.837 に答える
1

私はこのような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";
    }
}
于 2012-12-19T14:00:01.817 に答える
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   ║
╚══════════════════════════════════════╝
于 2012-12-19T14:02:13.377 に答える