可以說我有一個字符串列表:兩個列表的補充?
A,B,C,d
然後串
的另一份名單B,C,d
我想知道哪些要素在第一個列表中不在第二個列表中,所以結果將是A
我不知道要做到這一點的擴展方法的名稱是。我知道我可以使用concat,union和intersect進行類似的列表比較,但只是不知道要完成這個特定任務的名稱。
附錄,我對重複,因此,如果第一列表是:
A,A,A,B,C,d
和第二列表是
B,C ,d
我想
A,A,A
謝謝!
可以說我有一個字符串列表:兩個列表的補充?
A,B,C,d
然後串
的另一份名單B,C,d
我想知道哪些要素在第一個列表中不在第二個列表中,所以結果將是A
我不知道要做到這一點的擴展方法的名稱是。我知道我可以使用concat,union和intersect進行類似的列表比較,但只是不知道要完成這個特定任務的名稱。
附錄,我對重複,因此,如果第一列表是:
A,A,A,B,C,d
和第二列表是
B,C ,d
我想
A,A,A
謝謝!
可以使用Except Extension Method來獲取列表不在第二列表中的所有元素:
var result = list1.Except(list2);
var result = list1.Where(i => !list2.Contains(i));
這裏沒有內置的擴展方法嗎? – sooprise 2011-05-09 15:57:46
+1這正是我所要做的。 – 2011-05-09 15:58:55
您可以構建一個擴展方法來完成此操作。 – 2011-05-09 15:59:12
的「除」,在BCL方法移除所有重複,這是不是有什麼你要。
如果問題中的列表很大,那麼爲了有效地做到這一點,您可能需要浪費內存以換取時間節省。例如:
// yield all members of "sequence" omitting those in "except"
static IEnumerable<string> Filter(
this IEnumerable<string> sequence,
IEnumerable<string> except)
{
var set = new HashSet<string>(except); // Burn memory to save time
return from item in sequence
where !set.Contains(item)
select item;
}
這樣,每次測試項目時都可以快速查找。
與
var sequence = new List<string>() { A, B, A, C, D };
var except = new List<string>() { B, C };
var result = sequence.Filter(except).ToList();
請注意,如果第一個列表是A,A,B和第二個列表A,則這將返回B. – Brian 2011-05-09 20:39:59
如果你重複的定義包括兩個列表和要高效地計算補調用它,那麼你就需要使用不同的數據結構:一個袋子。一個包是一個允許重複的集合。
下面是一個名爲BagDifference
的擴展方法,它有效地解釋了任一列表中的重複項以及由Eric的答案啓發的示例程序。
public class Bag<T> : Dictionary<T, int>
{
public Bag(IEnumerable<T> sequence)
{
foreach (var item in sequence)
{
if (!ContainsKey(item)) this[item] = 0;
++this[item];
}
}
}
public static class EnumerableExtensions
{
public static IEnumerable<T> BagDifference<T>(this IEnumerable<T> sequence1, IEnumerable<T> sequence2)
{
var bag1 = new Bag<T>(sequence1);
var bag2 = new Bag<T>(sequence2);
foreach (var item in bag1.Keys)
{
var count1 = bag1[item];
var count2 = bag2.ContainsKey(item) ? bag2[item] : 0;
var difference = Math.Max(0, count1 - count2);
for (int i = 0; i < difference; i++)
yield return item;
}
}
}
class Program
{
static void Main(string[] args)
{
var sequence = new List<string>() { "A", "B", "A", "C", "D" };
var except = new List<string>() { "A", "B", "C", "C" };
var difference = sequence.BagDifference(except).ToList();
}
}
使用集合,如果你用小列表進行幾次以上的操作。這不僅是更合適的方法,而且複雜性也要好上千倍。 – delnan 2011-05-09 15:57:57
謝謝,這個問題涉及數千行 – sooprise 2011-05-09 16:06:35