K.R.
K.R.

Reputation: 329

C# comparing collections

I'm new to C# and need some help with comparing collections. I have two List<string> collections with their contents as below:

Collection Old: {"AAA","BBB","CCC"}

Collection New: {"BBB","CCC","DDD"}

I want to get a collection like below:

Collection Final: {"AAA", "Remove"; "BBB", "Keep"; "CCC", "Keep"; "DDD", "Add"}

How can I do this?

Upvotes: 3

Views: 784

Answers (5)

nawfal
nawfal

Reputation: 73311

If you have this method

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

you should be able to write:

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 })
);

Of course you can use the built-in Enumerable.Concat method but I find mine more elegant.

Upvotes: 0

Jon Egerton
Jon Egerton

Reputation: 41589

In 1 line (sort of)!

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();

Note: This is a developer fusion conversionof the below vb.net which does work - I've not had chance to test the c# version:

 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

Upvotes: 0

alexl
alexl

Reputation: 6851

            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));
            }

Upvotes: 1

Miguel Angelo
Miguel Angelo

Reputation: 24212

You can use a dictionary to do this...

at the end, each element in the dictionary will tell you how many items of each kind were removed or added.

It will indicate this with a count, not a simple 3 state flag... that is because you may have added or removed repeated items... what if you insert 3 AAA's in the second collection.

        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;
        }

The end result will look like this:

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

Upvotes: 0

Kieren Johnstone
Kieren Johnstone

Reputation: 42013

old.Except(new) will give you those items to remove

new.Except(old) will give you items to add

old.Intersect(new) will give you items to keep

(This is assuming you don't mind using the System.Linq namespace)

Or if you prefer, you can consider each item individually and check the existence in each list

Upvotes: 8

Related Questions