Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

compare two two generic list of strings

Posted on 2014-11-30
9
Medium Priority
?
989 Views
Last Modified: 2014-12-01
Dear experts:
Please help to implement the following two generic list of strings comparison:
Input: Two lists: cs1 and cs2 (List<string>)
Logic: Method must compare both cs1 and cs2 as follows:
If a string is in cs1 but not in cs2 then add string to Added list.
If a string is in not in cs1 but it is in cs2 then add string to Deleted list.
If a string is in both cs1 and cs2 then ignore it.

Output: Two lists: Added and Deleted  as List<string>

The answer could be written as a method in C# or VB.NET. Input list sizes can vary from 3 to 280 items.

e.g. cs1: abc, def, fgh
cs2: abc, xyz
Added: def, fgh.
Deleted:  xyz.

Thanks,

mas
0
Comment
Question by:Miguel Oz
  • 3
  • 3
  • 2
  • +1
9 Comments
 
LVL 11

Accepted Solution

by:
louisfr earned 1200 total points
ID: 40473184
The Except extension method is what you need:
List<string> Added = cs1.Except(cs2).ToList();
List<string> Deleted = cs2.Except(cs1).ToList();

Open in new window

0
 
LVL 8

Assisted Solution

by:Jean Marie Geeraerts
Jean Marie Geeraerts earned 400 total points
ID: 40473211
louisfr is correct.
Here's a complete code example of how to use an extension method with generic IEnumerables.

This is in a console application where the extension method is called directly from Program.cs
The example demonstrates for both a list of strings and a list of integers using the same generic method.
using System;
using System.Collections.Generic;

namespace EE
{
    class Program
    {
        static void Main(string[] args)
        {
            CompareTwoStringLists();
            Console.Clear();
            CompareTwoIntegerLists();
        }

        private static void CompareTwoStringLists()
        {
            var cs1 = new[] {"abc", "def", "fgh"};
            var cs2 = new[] {"abc", "xyz"};

            IEnumerable<string> added;
            IEnumerable<string> deleted;

            cs1.FindAddedAndDeleted(cs2, out added, out deleted);

            string addedOutput = string.Join(",", added);
            string deletedOutput = string.Join(",", deleted);

            Console.WriteLine("Added: {0}", addedOutput);
            Console.WriteLine("Deleted: {0}", deletedOutput);
            Console.WriteLine();
            Console.WriteLine("Press a key to continue");
            Console.ReadKey();
       }

        private static void CompareTwoIntegerLists()
        {
            var ci1 = new[] { 1, 2, 3 };
            var ci2 = new[] { 2, 3, 4 };

            IEnumerable<int> addedIntegers;
            IEnumerable<int> deletedIntegers;

            ci1.FindAddedAndDeleted(ci2, out addedIntegers, out deletedIntegers);

            Console.Write("Added: ");
            foreach (var addedInteger in addedIntegers)
            {
                Console.Write("{0} ", addedInteger);
            }
            Console.WriteLine();
            Console.Write("Deleted: ");
            foreach (var deletedInteger in deletedIntegers)
            {
                Console.Write("{0} ", deletedInteger);
            }
            Console.WriteLine();
            Console.WriteLine("Press a key to continue");
            Console.ReadKey();

        }
    }
}

Open in new window

This is the static class that holds the extension method:
using System.Collections.Generic;
using System.Linq;

namespace EE
{
    public static class GenericExtensions
    {
        public static void FindAddedAndDeleted<T>(this IEnumerable<T> list, IEnumerable<T> original, out IEnumerable<T> added, out IEnumerable<T> deleted)
        {
            var first = list as IList<T> ?? list.ToList();
            var second = original as IList<T> ?? original.ToList();
            added = first.Except(second);
            deleted = second.Except(first);
        }

        public static void FindAddedAndDeleted(this IEnumerable<object> list, IEnumerable<object> compareToList, out IEnumerable<object> added, out IEnumerable<object> deleted)
        {
            var first = list as IList<object> ?? list.ToList();
            var second = compareToList as IList<object> ?? compareToList.ToList();
            added = first.Except(second);
            deleted = second.Except(first);
        }
    }
}

Open in new window

The static class uses a generic method so you can compare any IEnumerable object.
0
 
LVL 35

Assisted Solution

by:it_saige
it_saige earned 400 total points
ID: 40473783
As louis pointed out, you can use Except.  Jean also provides a great example (although, you need to convert the Enumerables added and deleted to arrays for the string.Join methods overloads).
using System;
using System.Collections.Generic;
using System.Linq;

namespace EE_Q28571938
{
	class Program
	{
		static void Main(string[] args)
		{
			CompareTwoStringLists();
			Console.Clear();
			CompareTwoIntegerLists();
		}

		private static void CompareTwoStringLists()
		{
			var cs1 = new[] { "abc", "def", "fgh" };
			var cs2 = new[] { "abc", "xyz" };

			IEnumerable<string> added;
			IEnumerable<string> deleted;

			cs1.FindAddedAndDeleted(cs2, out added, out deleted);

			string addedOutput = string.Join(",", added.ToArray());
			string deletedOutput = string.Join(",", deleted.ToArray());

			Console.WriteLine("Added: {0}", addedOutput);
			Console.WriteLine("Deleted: {0}", deletedOutput);
			Console.WriteLine();
			Console.WriteLine("Press a key to continue");
			Console.ReadKey();
		}

		private static void CompareTwoIntegerLists()
		{
			var ci1 = new[] { 1, 2, 3 };
			var ci2 = new[] { 2, 3, 4 };

			IEnumerable<int> addedIntegers;
			IEnumerable<int> deletedIntegers;

			ci1.FindAddedAndDeleted(ci2, out addedIntegers, out deletedIntegers);

			Console.Write("Added: ");
			foreach (var addedInteger in addedIntegers)
			{
				Console.Write("{0} ", addedInteger);
			}
			Console.WriteLine();
			Console.Write("Deleted: ");
			foreach (var deletedInteger in deletedIntegers)
			{
				Console.Write("{0} ", deletedInteger);
			}
			Console.WriteLine();
			Console.WriteLine("Press a key to continue");
			Console.ReadKey();

		}
	}

	static class Extensions
	{
		public static void FindAddedAndDeleted<T>(this IEnumerable<T> source, IEnumerable<T> comparer, out IEnumerable<T> added, out IEnumerable<T> deleted)
		{
			var first = source as IList<T> ?? source.ToList();
			var second = comparer as IList<T> ?? comparer.ToList();
			added = first.Except(second);
			deleted = second.Except(first);
		}
	}
}

Open in new window


Produces the following output -Capture.JPGCapture.JPG
-saige-
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 11

Expert Comment

by:louisfr
ID: 40473803
If using the Framework 4 or above, you don't need to produce an array.
String.Join has been added an overload taking an Enumerable.
0
 
LVL 35

Expert Comment

by:it_saige
ID: 40473827
I should have been more specific with my correction of Jean's example.  :(  Thanks for the pickup louis.  ;)

Also, as a point of clarification to what I had stated above:

As louis pointed out, you *should* use... as opposed to, you *can* use...  With something like this, there is really no need to reinvent the wheel, as it were.

-saige-
0
 
LVL 8

Expert Comment

by:Jean Marie Geeraerts
ID: 40473864
Totally agree with above, no need to reinvent the wheel, so I used louisfr 's hint to provide the asker with a working example. As of such, if asker would consider my answer the one to help him/her, at least points would need to be divided as I only extended the solution provided by louisfr!!

For the string.Join, this does indeed work with an IEnumerable in the latest .Net version and I did just put a quick string.Join in the example for a nice UI output in the console application, how the result is presented is of course up to the requirements.

For the int version I didn't bother to use a stringbuilder or whatever, after all it's just a quick and dirty demo application :-)

Big advantage of the generic extension is that you can use it on any IEnumerable and immediately get the two IEnumerables for added/deleted lists. Otherwise it just uses what .Net has available through linq.
0
 
LVL 35

Expert Comment

by:it_saige
ID: 40474029
@Jean, it was not my intent to make it seem as if you were reinventing the wheel.  I hope you did not take it that way.  As for points; I expect no points from this, just ensuring the the author was provided a visual example of the output.

-saige-
0
 
LVL 36

Author Closing Comment

by:Miguel Oz
ID: 40474661
Thanks
0
 
LVL 8

Expert Comment

by:Jean Marie Geeraerts
ID: 40475324
Hi it_saige, no worries. I didn't take it that way. Just clarified my example a bit further and wanted to point out that I agreed with the proposed solution and just elaborated on it, thus making sure the correct expert (=louisfr) got his recognition :-)
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
This course is ideal for IT System Administrators working with VMware vSphere and its associated products in their company infrastructure. This course teaches you how to install and maintain this virtualization technology to store data, prevent vuln…
In a question here at Experts Exchange (https://www.experts-exchange.com/questions/29062564/Adobe-acrobat-reader-DC.html), a member asked how to create a signature in Adobe Acrobat Reader DC (the free Reader product, not the paid, full Acrobat produ…
Suggested Courses

885 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question