26871


以下のようなリスト
list1,list2がある場合に、list1とlist2の要素の値を比較し、一致していない要素をlist1に格納するという処理を実現したいと考えています。

要素配列の比較の仕方を工夫したいと考えているのですが  
.NET Framework
2.0での開発になりますので、IStructuralEquatable.Equalsメソッドを利用して配列の比較を行うことができません。  
リストの要素ごとのループに加えて配列の中身もループさせて比較していくような方法以外に  
安全で高速に配列同士を比較する方法はないでしょうか？  
初歩的な内容で申し訳ありませんが、よろしくお願いいたします。

[code]

              //1つめのリスト　list1
              string[] ary1_list1 = new string[] { "1", "1" };
              string[] ary2_list1 = new string[] { "1", "2" };
    
              List<String[]> list1  = new List<string[]>();
              list1.Add(ary1_list1);
              list1.Add(ary2_list1);
    
    
              //2つめのリスト list2
              List<String[]> list2  = new List<string[]>();
    
              string[] ary1_list2 = new string[] { "1", "1" };
              string[] ary2_list2 = new string[] { "1", "3" };
              string[] ary3_list2 = new string[] { "1", "5" };
              string[] ary4_list2 = new string[] { "1", "7" };
              string[] ary5_list2 = new string[] { "2", "2" };
              string[] ary6_list2 = new string[] { "2", "4" };
              list2.Add(ary1_list2);
              list2.Add(ary2_list2);
              list2.Add(ary3_list2);
              list2.Add(ary4_list2);
              list2.Add(ary5_list2);
              list2.Add(ary6_list2);
    
[/code]


CC BY-SA 3.0
2016-06-19T14:08:42.640
26868
2016-06-19T22:40:28.020
10614
question
c#
要素が配列のリストの比較について


基本的には1要素ずつ比較するしかありませんが、`IEqualityComparer<String[]>`や`IComparer<String[]>`のような型を実装すればそれらを受け入れるメソッドがあるため多少シンプルにまとめる事が出来ます。

加えて`list1`が昇順に並ぶという制限を付け加えると、`List<T>.BinarySearch(T,
IComparer<T>)`を使用して計算量のオーダーを下げる事が出来ます。つまり、

[code]

    class ArrayComaparer : IComparer<String[]>
    {
        public int Compare(String[] x, String[] y)
        {
            int c = Math.Min(x.Length, y.Length);
            for (var i = 0; i < c; i++)
            {
                int r = String.Compare(x[i], y[i]);
                if (r != 0)
                {
                    return r;
                }
            }
            return x.Length - y.Length;
        }
    }
    
[/code]

のような比較子を実装すれば、

[code]

    ArrayComaparer cp = new ArrayComaparer();
    foreach (String[] ary in list2)
    {
        int p = list1.BinarySearch(ary, cp);
        if (p < 0)
        {
            list1.Insert(~p, ary);
        }
    }
    
[/code]

と比較的シンプルになります。


CC BY-SA 3.0
2016-06-19T15:00:46.387
26871
2016-06-19T15:00:46.387
5750
26868
answer


まず.NET
4以降の`IStructuralEquatable`を使用したところで、本質的には各要素の比較を行うことには変わらないため特に高速化されるものではなく、ソースコードの記述量が削減できるだけです。

pgrhoさんが書かれているように比較子を用意することでソースコードを読みやすくすることはできますが、そのあたりは質問文に書かれていない条件で記述内容は変わってきます。例えばpgrhoさんのコードでも昇順に並ぶという条件を加えたりしていますし、`string[]`の要素数が固定長であればそれを基にした比較が行えるわけです。

これらは`string[]`という値の持ち方に原因があると思います。適切な型を用意すべきで、その型が比較子を持っていれば`List<T>.Contains()`で判定できます。


CC BY-SA 3.0
2016-06-19T22:40:28.020
26873
2016-06-19T22:40:28.020
4236
26868
answer