Làm thế nào để viết Inequality JOIN trong Linq (in-memory, không liên kết SQL gì cả)?

Ví dụ cho lệnh này:

candidateSet = filteredKeys.Join(
   filteredKeys,
   item1 => item1.Take(level),
   item2 => item2.Take(level),
   (item1, item2) => item1.Union(item2), new IntsEqualityComparer()
);

Dạng query syntax tương ứng là thế này (rất tiếc chỉ là minh họa, query syntax không cho phép thêm Custom Comparer, nhưng cái này ko cần bàn tới):

candidateSet = from item in filteredKeys
               join item2 in filteredKeys
               on item1.Take(level) equals item2.Take(level)
               select item1.Union(item2);

Và mình muốn thêm một điều kiện nữa, đó là:

item1 not equal item2

Tức là mình muốn làm phép Self join, nhưng tồn tại 1 điều kiện đặc biệt là 1 phần tử bất kì thì không được join với chính nó.
Hiện tại thì mình phải bổ sung 1 phép filter để loại bỏ trường hợp 1 phần tử join với chính nó:

candidateSet = filteredKeys.Join(
   filteredKeys,
   item1 => item1.Take(level),
   item2 => item2.Take(level),
   (item1, item2) => item1.Union(item2), new IntsEqualityComparer()
)
.Where(item => item.Count() > 1)

Mình đã google rất nhiều, và không ra được cách nào hay hơn cách này cho trường hợp tổng quát (minh họa):

candidateSet = from item in filteredKeys
               from item2 in filteredKeys
               where item1 != item2 && item1.Take(level) != item2.Take(level)
               select item1.Union(item2);

Cách này rất tệ, tích đề-các này có thể làm đầy bộ nhớ không còn chỗ thở (nhớ là mình đang làm in-memory chứ không phải là LINQ to SQL)
Thành ra có bạn nào từng gặp vấn đề này và biết con đường giải quyết triệt để không :frowning:

Vậy là vẫn như mọi khi rồi :blush:

2 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?