2

私は2つのコレクションを持っています。

  var a = new List<string>() { "a", "b", "c", "d", "e", "f", "j" };
  var b = new List<string>() { "a", "c", "d", "h", "i" };

そして、あるコレクションまたは別のコレクションに欠落している場合に備えて、アイテムに対して何らかのアクションを実行したいと思います.

public static Synchronize<T>(IEnumerable<T> first, IEnumerable<T> second, Action<T> firstSynchronizer, Action<T> secondSynchronizer)
{
  var firstUnique = first.Distinct();
  var secondUnique = second.Distinct();
  foreach (var item in firstUnique)
  {
    if (!secondUnique.Contains(item)) firstSynchronizer(item);
  }
  foreach (var item in second.Distinct())
  {
    if (!firstUnique.Contains(item)) secondSynchronizer(item);
  }
}

これは私が得たものですが、満足していません。これを実装するためのより良い方法があるかどうか疑問に思わDistinct()ずにはいられません。パフォーマンスにかなり大きな影響があると思います。上記のように)または反復する方がよい場合はsecond.Except(first)?皆さんはどう思いますか?

私はそれを次のように呼びます:

  var a = new List<string>() { "a", "b", "c", "d", "e", "f", "j" };
  var b = new List<string>() { "a", "c", "d", "h", "i" };
  Synchronize(a.ToArray(), b.ToArray(), t => b.Add(t), t => a.Add(t));

ToArray()コレクションが繰り返されている間に変更されないように呼び出し、ラムダは不足している要素をそれぞれのリストに追加するだけです。

また、これは単なるテスト実装です。本番環境では、Enumerables は同じ型にはなりません。これは、リモート ストレージとローカル ストレージの同期に使用することを目的としています。将来的には、Enumerable が最初に例ICollection<DummyRemoteItem>になり、Enumerable が 2 番目になりますList<IO.FileSystemInfo>。しかし、私はそれをより一般的にしたいと考えています。Func<T1, T2, bool>さまざまなコレクションを操作できるようにするために、別の型パラメーターとアイテムを比較するための を提案すると思います。それが最善のアプローチですよね?

一般的に、の内部を実装する最良の方法は何ですか

Synchronize<T>(IEnumerable<T> first,IEnumerable<T> second,Action<T> firstSynchronizer,Action<T> secondSynchronizer) 

Synchronize<TFirst, TSecond>(IEnumerable<TFirst> first,IEnumerable<TSecond> second,Action<TFirst> firstSynchronizer,Action<TSecond> secondSynchronizer, Func<TFirst, TSecond, bool> predicate)
4

4 に答える 4

0

Exceptメソッドとメソッドを使用してIntersect、2 つの列挙可能なソース間の相違点または同一の項目を見つけることができます。MSDN には、 ExceptIntersectの両方に関する多くのリソースがあります。

コストのかかるパフォーマンス ヒットについてのコメントについてDistinct()は、ヒットは軽微であり、最適化を試みるのは時期尚早であると思われます。

于 2012-07-20T10:57:30.460 に答える
0

最もエレガントな方法は、セットを使用することだと思います。.NET では HashSet が探しているものかもしれません。

http://msdn.microsoft.com/en-us/library/bb495294.aspx

于 2012-07-20T10:58:46.897 に答える
0

ここでは、Linq の完全外部結合があなたの味方です。

これが実装です(ここから)

public static IEnumerable<Tuple<T1, T2>> FullOuterJoin<T1, T2>
   (this IEnumerable<T1> one, IEnumerable<T2> two, Func<T1,T2,bool> match)
{
 var left = from a in one
   from b in two.Where((b) => match(a, b)).DefaultIfEmpty()
   select new Tuple<T1, T2>(a, b);

 var right = from b in two
   from a in one.Where((a) => match(a, b)).DefaultIfEmpty()
   select new Tuple<T1, T2>(a, b);

 return left.Concat(right).Distinct();
}

それで:

a.FullOuterJoin(b,a=>a,b=>b,(a,b)=>new {a,b})

結果の列挙型でnullを探します。

于 2012-07-20T10:59:45.403 に答える