Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

compare two two generic list of strings

Posted on 2014-11-30
9
Medium Priority
?
941 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 34

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
CHALLENGE LAB: Troubleshooting Connectivity Issues

Goal: Fix the connectivity issue in the lab's AWS environment so that you can SSH into the provided EC2 instance.  

 
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 34

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 34

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

Give Your Engineering Team a Productivity Boost

Learn why container technology is so powerful and how it can provide your team with productivity gains and other benefits.

Question has a verified solution.

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

This article is for Object-Oriented Programming (OOP) beginners. An Interface contains declarations of events, indexers, methods and/or properties. Any class which implements the Interface should provide the concrete implementation for each Inter…
The ECB site provides FX rates for major currencies since its inception in 1999 in the form of an XML feed. The files have the following format (reducted for brevity) (CODE) There are three files available HERE (http://www.ecb.europa.eu/stats/exch…
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…

721 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