簡體   English   中英

C#比較集合

[英]C# comparing collections

我是C#的新手,需要一些比較集合的幫助。 我有兩個List<string>集合,其內容如下:

收藏舊:{“AAA”,“BBB”,“CCC”}

收藏新品:{“BBB”,“CCC”,“DDD”}

我想得到如下的集合:

收集決賽:{“AAA”,“刪除”; “BBB”,“保持”; “CCC”,“保持”; “DDD”,“添加”}

我怎樣才能做到這一點?

old.Except(new)將為您提供要刪除的項目

new.Except(old)將為您提供要添加的項目

old.Intersect(new)會為你提供物品

(這假設您不介意使用System.Linq命名空間)

或者如果您願意,可以單獨考慮每個項目並檢查每個列表中是否存在

            var oldList = new List<String>() {"AAA", "BBB", "CCC"};
            var newList = new List<String>() {"BBB", "CCC", "DDD"};

            var diffDictionary = new Dictionary<string, string>();

            foreach (var oldEntry in oldList)
            {
                diffDictionary.Add(oldEntry, "Remove");
            }

            foreach (var newEntry in newList)
            {
                if (diffDictionary.ContainsKey(newEntry))
                {
                    diffDictionary[newEntry] = "Keep";
                }
                else
                {
                    diffDictionary.Add(newEntry, "Add");
                }
            }

            foreach (var dDico in diffDictionary)
            {
                Console.WriteLine(string.Concat("Key: ", dDico.Key, " Value: ", dDico.Value));
            }

如果你有這個方法

public static IEnumerable<T> Concat<T>(params IEnumerable<T>[] sequences)
{
    return sequences.SelectMany(x => x);
}

你應該寫:

static readonly string Remove = "Remove";
static readonly string Keep = "Keep";
static readonly string Add = "Add";

var result = Concat
(
    old.Except(new).Select(x => new { x, Remove }), 
    old.Intersect(new).Select(x => new { x, Keep }), 
    new.Except(old).Select(x => new { x, Add })
);

當然你可以使用內置的Enumerable.Concat方法,但我發現它更優雅。

你可以用字典來做這件事......

最后,字典中的每個元素都會告訴您刪除或添加了多少項。

它會用計數來表示這個,而不是簡單的3狀態標志...這是因為你可能已經添加或刪除了重復的項目...如果你在第二個集合中插入3個AAA會怎樣。

        string[] col1 = new string[] { "AAA", "BBB", "CCC" };
        string[] col2 = new string[] { "BBB", "CCC", "DDD" };

        Dictionary<string, int> colDic = new Dictionary<string, int>();
        foreach (var item in col1)
        {
            int num;
            if (colDic.TryGetValue(item, out num))
                colDic[item] = num - 1;
            else
                colDic[item] = -1;
        }

        foreach (var item in col2)
        {
            int num;
            if (colDic.TryGetValue(item, out num))
                colDic[item] = num + 1;
            else
                colDic[item] = 1;
        }

最終結果如下所示:

AAA = -1
BBB = 0
CCC = 0
DDD = 1

1行(有點)!

string[] colOld = {"AAA","BBB","CCC"};
string[] colNew = {"BBB","CCC","DDD"};

dynamic colALL = (from o in colOld.Union(colNew)
                  select new {Value = o, Action = 
                              colOld.Any(s => s == o) ? 
                                  colNew.Any(s => s == o) ? "Keep" : "Remove" 
                              : "Add"
                           }).ToList();

注意:這是以下vb.net的開發人員融合轉換,它確實有效 - 我沒有機會測試c#版本:

 Dim colOld() As String = {"AAA", "BBB", "CCC"}
    Dim colNew() As String = {"BBB", "CCC", "DDD"}

    Dim colALL = (From o As String In colOld.Union(colNew) _
                    Select New With {.Value = o, .Action = _
                                     If(colOld.Any(Function(s) s = o), _
                                        If(colNew.Any(Function(s) s = o), "Keep", "Remove"), _
                                        "Add")}).ToList

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM