リストA:リストAをチェックするにはリストBの値が含まれていますか?
1, 2, 3, 4
リストB:リストA、リストBから任意の値が含まれているかどうかを確認する方法
2, 5
?
A.contains(a => a.id = B.id)のようなもの?
リストA:リストAをチェックするにはリストBの値が含まれていますか?
1, 2, 3, 4
リストB:リストA、リストBから任意の値が含まれているかどうかを確認する方法
2, 5
?
A.contains(a => a.id = B.id)のようなもの?
あなたはパフォーマンスを気にしなかった場合、あなたは試みることができる:
a.Any(item => b.Contains(item))
// or, as in the column using a method group
a.Any(b.Contains)
しかし、私はこれが最初しようとするだろう:
a.Intersect(b).Any()
あなたは二つのリストIntersect
ことができます。
if (A.Intersect(B).Any())
を
私はJustinsの2つのソリューションのプロファイルを作成しました。 a.Any(a => b.Contains(a))
は最速ですです。
using System;
using System.Collections.Generic;
using System.Linq;
namespace AnswersOnSO
{
public class Class1
{
public static void Main(string []args)
{
// How to check if list A contains any value from list B?
// e.g. something like A.contains(a=>a.id = B.id)?
List<int> a = new List<int> {1,2,3,4};
List<int> b = new List<int> {2,5};
int times = 10000000;
DateTime dtAny = DateTime.Now;
for (int i = 0; i < times; i++)
{
var aContainsBElements = a.Any(b.Contains);
}
var time = (DateTime.Now - dtAny).TotalSeconds;
DateTime dt2 = DateTime.Now;
for (int i = 0; i < times; i++)
{
var aContainsBElements = a.Intersect(b).Any();
}
var time2 = (DateTime.Now - dt2).TotalSeconds;
// time1: 1.1470656 secs
// time2: 3.1431798 sec
}
}
}
私はそれを設定するためのより速い方法を書くことができます。しかし、私はいくつかのデータでそれをテストします。それは、ある程度高速ですが、Intersectは速いです。
public static bool Contain<T>(List<T> a, List<T> b)
{
if (a.Count <= 10 && b.Count <= 10)
{
return a.Any(b.Contains);
}
if (a.Count > b.Count)
{
return Contain((IEnumerable<T>) b, (IEnumerable<T>) a);
}
return Contain((IEnumerable<T>) a, (IEnumerable<T>) b);
}
public static bool Contain<T>(IEnumerable<T> a, IEnumerable<T> b)
{
HashSet<T> j = new HashSet<T>(a);
return b.Any(j.Contains);
}
交差は、第2のサイズをチェックしていないSet
を呼び出し、これは交差のコードです。
Set<TSource> set = new Set<TSource>(comparer);
foreach (TSource element in second) set.Add(element);
foreach (TSource element in first)
if (set.Remove(element)) yield return element;
二つの方法の違いは、私の方法はHashSet
を使用してカウントし、HashSet
よりも高速であるIntersect
使用set
を確認しています。私たちはその性能を傷つけません。
テスト:
static void Main(string[] args)
{
var a = Enumerable.Range(0, 100000);
var b = Enumerable.Range(10000000, 1000);
var t = new Stopwatch();
t.Start();
Repeat(()=> { Contain(a, b); });
t.Stop();
Console.WriteLine(t.ElapsedMilliseconds);//490ms
var a1 = Enumerable.Range(0, 100000).ToList();
var a2 = b.ToList();
t.Restart();
Repeat(()=> { Contain(a1, a2); });
t.Stop();
Console.WriteLine(t.ElapsedMilliseconds);//203ms
t.Restart();
Repeat(()=>{ a.Intersect(b).Any(); });
t.Stop();
Console.WriteLine(t.ElapsedMilliseconds);//190ms
t.Restart();
Repeat(()=>{ b.Intersect(a).Any(); });
t.Stop();
Console.WriteLine(t.ElapsedMilliseconds);//497ms
t.Restart();
a.Any(b.Contains);
t.Stop();
Console.WriteLine(t.ElapsedMilliseconds);//600ms
}
private static void Repeat(Action a)
{
for (int i = 0; i < 100; i++)
{
a();
}
}
私はカウントするためにこれを使用する:魅力のような
int cnt = 0;
foreach (var lA in listA)
{
if (listB.Contains(lA))
{
cnt++;
}
}
Countが要求されていません。これは非常に非効率的で、必須のコードです。 –
ブール値の代わりにカウントを使用した理由など、この回答のための説明がもう少しあるかもしれません。これは仕事をやってもらう*。 – Taegost
作品。あなたは最初の回答者なので、私は答えとしてあなたの印をつけました。ありがとう。 – wahaha
リストとラムダの両方に 'a'を使用することはできません。 'a.Any(a => b.Contains(a))'。代わりにメソッドグループを使用することをお勧めします。 – radbyx