Solved

compare two two generic list of strings

Posted on 2014-11-30
9
723 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 300 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 100 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 32

Assisted Solution

by:it_saige
it_saige earned 100 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
 
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
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 32

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 32

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 35

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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

This document covers how to connect to SQL Server and browse its contents.  It is meant for those new to Visual Studio and/or working with Microsoft SQL Server.  It is not a guide to building SQL Server database connections in your code.  This is mo…
Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

758 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

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now