4

連絡先と従業員の2つのリストがあります。従業員ではない連絡先のサブセットを生成したいと思います。次の式は、従業員ではない連絡先がいくつかあることを示すのに役立つようです。次に、その基準に一致する連絡先のリストが必要です。

if(myContacts.Select(c=>c.contactID).Except(employees.Select(e=>e.contactID)).Any()
{
   //get the subset of contacts and do stuff to them....
}

TIA!

ロン

4

3 に答える 3

3
 var nonEmployees = contacts.Where(w=> ! employees.Any(e=>e.contactID == w.contactID)).ToList();

また

 var nonEmployees = contacts.Where(w=> ! employees.Select(s=>s.contactID).Contains(w.contactID) ).ToList();
于 2012-08-07T15:25:09.800 に答える
2

employeesとシーケンスが同じタイプのオブジェクトである場合contacts(または両方がのように同じタイプから継承する場合Contact)、EqualityComparerインスタンスを作成できます。

public class ContactComparer : EqualityComparer<Contact>
{
    public override bool Equals(Contact x, Contact y)
    {
        if (ReferenceEquals(x, y)) return true;

        return x != null && y != null && x.ContactId == y.ContactId;
    }

    public override int GetHashCode(Contact obj)
    {
        if (obj == null) throw new ArgumentNullException("obj");

        // assuming string
        return (obj.ContactId ?? "").GetHashCode();
    }
}

これにより、これを実行できるため、結果を直接返すだけで、二重クエリを実行する必要がなくなります。

var contactsNotEmployees = myContacts.Except(employees, new ContactComparer()).ToList();

更新:コメントが示すようにContactとEmployeeが別々のタイプであるため、ContactIdプロパティを使用してインターフェイスを作成し、共通の結合を作成することを検討できます。

または、例外の結果をaにエクスポートしてから、からHashSetを使用することをお勧めします。これは、O(n)効率であるシーケンスではなく、O(1)効率です。Contains()HashSetContains()

 // get hash set of contact-only IDs
 var except = new HashSet<int>(contacts
      .Select(c => c.ContactId)
      .Except(emplopyees.Select(e => e.ContactId)));

 // get the objects for those IDs
 var others = contacts.Where(c => except.Contains(c.ContactId)).ToList();

Contains()シーケンスを使用した結果を比較すると、HashSet Contains()小さいリスト(15アイテム)の場合は約50%速くなり、長いリストの場合はさらに速くなります。

IEnumerable<T>とにかく、シーケンス()のContains( )は比較的遅いので、それを捨てるだけです...

私は両方のソリューションの時間を1,000,000回以上繰り返して、次のようにしました。

 HashSet With Contains() took: 1429 ms, 0.001429 ms/item.
 Sequence With Contains() took: 3386 ms, 0.003386 ms/item.
于 2012-08-07T15:34:27.967 に答える
1

これはすでにあなたが探しているものではありませんか?

myContacts.Select(c=>c.contactID)
          .Except(employees.Select(e=>e.contactID)
          .ToList()
于 2012-08-07T15:24:01.367 に答える