このアプローチは非常に非効率的です。新しいf1
で開始するたびにdir2.GetFiles
と呼ぶ予定です。 f2
がの現在のf1
と一致しない場合は、一致するようにします。たとえそれがの後にf1
と一致しても、出力されます。そのDIR1は、A、BおよびCが含まれており、DIR2は、CおよびDが含まれています。このように終わるだろうと想像:だから、結果はA、A、B、B、Cになり
f1 f2 Result of where?
A C True
A D True
B C True
B D True
C C False
C D True
- あなたがしたいですまだは(あなたが望んしなかった) Cを持っている - だけでなく、かなりのように、多くの場合、AとB
としてあなたはこのように、集合演算を使用したい:今すぐ
var dir1Files = dir1.GetFiles("*", SearchOption.AllDirectories)
.Select(x => x.Name);
var dir2Files = dir2.GetFiles("*", SearchOption.AllDirectories)
.Select(x => x.Name);
var onlyIn1 = dir1Files.Except(dir2Files);
そのべき仕事、そしてより効率的に...
編集:以前のバージョンの質問に基づいて、AのファイルがBのファイルではないとします。 (私はそれが最初の5分に編集されたかどうかわからないんだけど、明らかに現在のコードはBではなくAに何かを返すために行くのではありません)あなたは、対称差をつけたい場合は
、HashSet<T>.SymmetricExceptWith
を使用します。
var inExactlyOneDirectory = new HashSet<string>(dir1Files);
inExactlyOneDirectory.SymmetricExceptWith(dir2Files);
SymmetricExceptWith
は、新しいセットまたはシーケンスだけを返す代わりに、既存のセットを変更するvoidメソッドであるという点を嫌います。他のものとは別に、変数名は最初のものではなく2番目のステートメント)
EDIT:名前とサイズによって一意性が必要な場合は、r両方を表す匿名型が必要です。残念ながら、それに基づいてHashSet<T>
を作成するのは難しいです。ですから、このような拡張メソッドをお勧めします:
public static HashSet<T> ToHashSet<T>(this IEnumerable<T> set)
{
return new HashSet<T>(set);
}
その後:あなたの現在のソリューションが動作しませんなぜ
var dir1Files = dir1.GetFiles("*", SearchOption.AllDirectories)
.Select(x => new { x.Name, x.Length });
var dir2Files = dir2.GetFiles("*", SearchOption.AllDirectories)
.Select(x => new { x.Name, x.Length });
var difference = dir1Files.ToHashSet();
difference.SymmetricExceptWith(dir2Files);
@Jon Skeet:OPは、dir1またはdir2にありますが、*両方ではないファイルが必要です。 – Ani
@Ani:元のコードに基づいて完全にはっきりしているわけではありません。この質問はもともと対称的な違いではなく「AではあるがBではない」ことを示唆していたと思います。しかし、対称的な違いも含めて答えを編集しました。 –
@ bala3569:あなたが何を意味するのか分かりませんが、答えには両方の解決策を提供しました。 –