Finding Differences In Sets - c#

I have this class (a partial listing):
class CiscoSwitch
{
private string _SwitchName = string.Empty;
public SwitchName {get {return _SwitchName;} set{_SwitchName=value; }}
}
I have 2 lists of CiscoSwitch objects. I am trying to compare them to pick out the ones that are not duplicates. I only want the duplicates. I tried a Lambda expression but got a compiler error that CiscoSwitch was a non-delgate type.
I am now wondering about something like this - it would allow me to use the List.Except() method (I think):
static class SwitchComparer
{
static bool CompareSwitchNames(CiscoSwitch s1, CiscoSwitch s2)
{
if (sw1.SwitchName == s2.SwitchName) {return true;}
else {return false;}
}
}
// to find the differences
// this is a method of the CiscoSwitchClass
private List<CiscoSwitch> FindDifferences(List<CiscoSwitch> List1, List<CiscoSwitch> List2)
{
return List1.Except(List2, SwitchComparer.CompareSwitchNames();
}
this could also be done with a foreach but I think this way is a lot cleaner, if it is correct. I am also thinking there are other attributes of a CiscoSwitch I might want to compare some day so could add methods to the SwitchComparer class as I need them.

No, just having a single method like that won't help you. You need to implement an IEqualityComparer<CiscoSwitch> to pass to Enumerable.Except - and even then your code would need to be:
return List1.Except(List2, new SwitchComparer()).ToList();
Overriding Equals and GetHashCode within CiscoSwitch will do the trick more naturally though - and ideally you should implement IEquatable<CiscoSwitch> too.
However, it's worth noting that mutable types like this don't play terribly nicely with things like Dictionary<,> - if you change an object in a way which affects its hash code after you've inserted it as a key into the dictionary, you won't be able to get at it again. Consider making the type immutable if you can.
A couple of other points to note:
Any time you write:
if (condition)
{
return true;
}
else
{
return false;
}
you should instead write the far simpler:
return condition;
So your CompareSwitchNames method would be:
static bool CompareSwitchNames(CiscoSwitch s1, CiscoSwitch s2)
{
return s1.SwitchName == s2.SwitchName;
}
Your parameter names for FindDifferences should follow .NET naming conventions (e.g. list1 and list2)
Using Except will only find you the elements in the first list which aren't in the second list; if you need to find the symmetric difference, consider using HashSet<T> explicitly.
EDIT: If you wanted to have multiple ways of comparing, you could have something like:
public static class SwitchComparers
{
public static readonly IEqualityComparer<CiscoSwitch> ByName =
new ByNameComparer();
public static readonly IEqualityComparer<CiscoSwitch> ByCost =
new ByCostComparer();
private sealed class ByNameComparer : IEqualityComparer<CiscoSwitch>
{
// Implementation
}
private sealed class ByCostComparer : IEqualityComparer<CiscoSwitch>
{
// Implementation
}
}

You could implement a custom comparer:
public class CiscoSwitchComparer : IEqualityComparer<CiscoSwitch>
{
public bool Equals(CiscoSwitch x, CiscoSwitch y)
{
return x.SwitchName.Equals(y.SwitchName));
}
public int GetHashCode(CiscoSwitch obj)
{
return obj.SwitchName.GetHashCode();
}
}
And then:
private List<CiscoSwitch> FindDifferences(List<CiscoSwitch> List1, List<CiscoSwitch> List2)
{
return List1.Concat(List2)
.Distinct(new CiscoSwitchComparer())
.ToList();
}

You should implement IEqualityComparer[T] interface.
This interface allows the implementation of customized equality
comparison for collections. That is, you can create your own
definition of equality for type T, and specify that this definition be
used with a collection type that accepts the IEqualityComparer
generic interface. In the .NET Framework, constructors of the
Dictionary generic collection type accept this
interface.
A default implementation of this interface is provided by the Default
property of the EqualityComparer generic class. The StringComparer
class implements IEqualityComparer of type String.
This interface supports only equality comparisons. Customization of
comparisons for sorting and ordering is provided by the IComparer
generic interface.
We recommend that you derive from the EqualityComparer class
instead of implementing the IEqualityComparer interface, because
the EqualityComparer class tests for equality using the
IEquatable.Equals method instead of the Object.Equals method. This
is consistent with the Contains, IndexOf, LastIndexOf, and Remove
methods of the Dictionary class and other generic
collections.

Related

Creating multiple custom comparators for a dictionary based class

I wish in my class to return a list from a dictionary but allow custom sorting using pre-written comparison methods. In my original java code that I'm converting from, I created compare methods using Google Guava Ordering in my class and then had a single method called the following passing in one of the public comparator methods, kind of declared like this:
public List<Word> getWords(Comparator c) { }
I'm trying to recreate this in C# but I can't figure out how. Essentially in the code below you can see there are three versions for each type of sort, and in addition I end up creating two lists for every return value which seems a bit wasteful.
I looked at creating delegates but got a bit lost, then figured I could create an IComparable, but then saw IComparator and then saw Sort method takes a Comparator.
Can somebody point me in the direction of converting this into a single sort 'GetWords' in the best way, allowing clients to call the GetWords retrieving a sorted list from a pre-supplied set of ordering.
public partial class WordTable
{
private Dictionary<string, Word> words;
public WordTable()
{
//for testing
words = new Dictionary<string, Word>();
words.Add("B", new Word("B", WordTypes.Adjective));
words.Add("A", new Word("A", WordTypes.Noun));
words.Add("D", new Word("D", WordTypes.Verb));
}
public List<Word> GetWords()
{
return words.Values.ToList();
}
public List<Word> GetWordsByName()
{
List<Word> list = words.Values.ToList<Word>();
return list.OrderBy(word => word.Name).ToList();
}
public List<Word> GetWordsByType()
{
List<Word> list = words.Values.ToList<Word>();
return list.OrderBy(word => word.Type).ToList();
}
}
I think you are looking for predicates.
Effectively, you want a predefined set of predicates (one for ByName, one for ByType), and you pass this predicate into the GetWords function.
There are two approaches you can use.
IComparer
This is more closely related to your past Java experience.
The official way is to use IComparer<T> (link).
Similar to your Comparator in the Java example, this enables you to create different sorting methods which all implement the IComparer<Word> interface, and then you can dynamically choose your sorting method.
As a simple example:
public class WordNameComparer : IComparer<Word>
{
public int Compare(Word word1, Word word2)
{
return word1.Name.CompareTo(word2.Name);
}
}
And then you can do:
public List<Word> GetWords(IComparer<Word> comparer)
{
return words.Values.OrderBy(x => x, comparer).ToList();
}
Which you can call by doing:
var table = new WordTable();
List<Word> sortedWords = table.GetWords(new WordNameComparer());
And of course you change the sorting logic by passing a different IComparer<Word>.
Func parameters
From experience, this is a much preferred approach due to LINQ's enhanced readability and low implementation cost.
Looking at your last two methods, you should see that the only variable part is the lambda method that you use to order the data. You can of course turn this variably into a method parameter:
public List<Word> GetWordsBy<T>(Func<Word,T> orderByPredicate)
{
return words.Values.OrderBy(orderBy).ToList();
}
Because the OrderBy predicate uses a generic parameter for the selected property (e.g. sorting on a string field? an int field? ...), you have to make this method generic, but you don't need to explicitly use the generic parameter when you call the method. For example:
var sortedWordsByName = table.GetWordsBy(w => w.Name);
var sortedWordsByLength = table.GetWordsBy(w => w.Name.Length);
var sortedWordsByType = table.GetWordsBy(w => w.Type);
Note that if you select a class, not a value type, that you will either still have to create and pass an IComparer<> for this class, or the class itself must implement IComparable<> so it can be sorted the way you want it to be.
You can introduce ascending/descending ordering:
public List<Word> GetWordsBy<T>(Func<Word,T> orderByPredicate, bool sortAscending = true)
{
return sortAscending
? words.Values.OrderBy(orderBy).ToList()
? words.Values.OrderByDescending(orderBy).ToList();
}
Update
I was trying to do it with delegates, but avoiding the caller having to roll their own lambda statement and use predefined ones.
You can simply wrap your method with some predefined options:
public List<Word> GetWordsBy<T>(Func<Word,T> orderByPredicate)
{
return words.Values.OrderBy(orderBy).ToList();
}
public List<Word> GetWordsByName()
{
return GetWordsBy(w => w.Name);
}
This way, your external callers don't need to use the lambda if they don't want to; but you still retain the benefits of having reusable code inside your class.
There are many ways to do this. I prefer creating preset methods for readability's sake, but you could instead have an enum which you then map to the correct Func. Or you could create some static preset lambdas which the external caller can reference. Or... The world is your oyster :-)
I hope this works, or even compiles.
class WordTable
{
public List<Word> GetWords(IComparer<Word> comparer)
{
return words.Values.OrderBy(x => x, comparer).ToList();
}
}
class WordsByNameAndThenTypeComparer : IComparer<Word>
{
public override int Compare(Word x, Word y)
{
int byName = x.Name.CompareTo(y.Name);
return byName != 0 ? byName : x.Type.CompareTo(y.Type);
}
}
Usage:
WordTable wt = new WordTable();
List<Words> words = wt.GetWords(new WordsByNameAndThenTypeComparer());

How to Make Collection Stop Calling Equals when Performing Collection.Remove

I have a Class Test which has a overriden method for "Equals" method and then I have a TestCollection class which is implemented using ICollection<Test> & IEnumerable<Test> in the Collection I have implemented Remove method which just removes the item from the current TestCollection object.
Whenever I class remove method for the TestCollection object, this internally calls "Equals" method which is overridden at Test class.
For one of my scenario, I do not want this Equals to be called, what are the other ways where I can remove the item from my collection without calling Equals
Below is the sample code for better understanding.
Test Class
public class Test
{
public int Id { get; set; }
private Collection<Test> _entities = new Collection<Test>();
public bool Remove(Test item)
{
return this._entities.Remove(item);
}
public override bool Equals(object obj)
{
Console.WriteLine("Equals inside Test Object");
return true;
}
}
TestCollection class
public class TestCollection : ICollection<Test>, IEnumerable<Test>
{
public TestCollection() : base() { }
private Collection<Test> _entities = new Collection<Test>();
public TestCollection(IList<Test> entityList)
{
this._entities = new Collection<Test>(entityList);
}
public bool Remove(Test item)
{
return this._entities.Remove(item);
}
public override bool Equals(object obj)
{
Console.WriteLine("Equals inside Test Collection Object");
return true;
}
}
I think you are missing the point here. Equals method is implementing the arithmetic relation of equivalence, like having attributes of being reflexive, symmetric and transitive. There are no two distinct ways to say that two objects are equal, you see?
Solution for you is to remove implementation of the Equals method. This method is intended to be overridden if and only if there is exactly one definition of equivalence for a class - like integer equality - there is exactly one way to test whether two integers are equal.
Also, that is the reason why Remove method does not accept an additional parameter such as an IComparer or IEqualityComparer - that wouldn't make sense.
On a related note: Entities should never override Equals. There is no equality relation (in mathematical terms) defined for objects that can change their state over time, and entity is defined as an object with lifetime. The trouble there is that you can pick two versions of the same entity and ask whether they are equal. Well, they are both equal (that is the same entity) and not equal (those are two versions of it). Therefore, Equals method is not the way to check equality of entities.
The short answer is that you cannot.
The way that an item is removed from a list is done by doing an equality check for the item in question on each of the entries in the list.
There may be some way to do it, however, but I doubt it's a good practice, or even desirable code.
You could wrap the list into another list that uses a custom IEqualityComparer implementation. Allow that comparer to have two different modes (pass through to object.Equals, or don't) and switch them before remove (and switch back afterwards).
You could find the index of the item you want to remove (not use its Equal) and call RemoveAt

Value equality for struct keys and reference equality for class keys in a dictionary

I'm implementing a generic dictionary. I want the TKey to be either a struct or a class. If it's a structure I want to compare keys by value, otherwise by reference.
I can't use neither Object.Equals (only works with structs) nor Object.ReferenceEquals (only works with reference types). What method do I use to test for equality then?
== operator would probably solve this issue but I can't use it without specifying any constraints for the key (where TKey : ...). What interfaces should I declare?
I can't use neither Object.Equals (only works with structs) nor Object.ReferenceEquals (only works with reference types).
It seems you may simply be mistaken about how these work. The System.Object.Equals() method implementation works equally well (no pun intended) whether dealing with a value type or a reference type.
For value types, it does a field-by-field comparison. If the two values being compared are the same type, and each of their fields have the same value, then they are considered equal.
For reference types, it simply uses reference equality, as you seem to want.
Note that types can override this method, so the actual implementation used could be different from the above. For example, the string type overrides the method, so that two strings which are not the same instance can still compare as equal. But by default, the above is what happens.
Finally I'll note that if what you want is a behavior that works exactly like the Dictionary<TKey, TValue> class, it may well be that the best solution is to just use that class. :)
You could do the following in your class:
public class MyCustomDictionary<TKey, TValue>
{
private static readonly Func<TKey, TKey, bool> _equalityComparer;
// ... other stuff
static MyCustomDictionary()
{
if (typeof(TKey).IsClass)
_equalityComparer = (lhs, rhs) => Object.ReferenceEquals(lhs, rhs)
else
_equalityComparer = (lhs, rhs) => lhs.Equals(rhs);
}
// ... other stuff
}
And use this equality comparer for comparisons.
The way this is normally done though, is by using an equality comparer IEqualityComparer<TKey>, like this:
public class MyCustomDictionary<TKey, TValue>
{
private readonly IEqualityComparer<TKey> _equalityComparer;
// ... other stuff
public MyCustomDictionary()
{
_equalityComparer = EqualityComparer<T>.Default;
}
public MyCustomDictionary(IEqualityComparer<T> comparer)
{
_equalityComparer = comparer;
}
// ... other stuff
}
This is what is done e.g. in the regular BCL System.Collections.Generic.Dictionary<TKey, TValue>, and other collections that need to do equality comparisons.
If you do not have very special needs (like I initially thought when I read your question), you should use the standard way of doing it with an IEqualityComparer<TKey>.
.NET generic dictionary using Equals and GetHashCode methods, that are virtual and available for both a struct and a class. So you can simply do the same, and just override those methods in you struct:
public struct KeyStructure
{
public override bool Equals(object obj)
{
// your implementation
}
public override int GetHashCode()
{
// your implementation
}
}
On other side, in general, if you want to use interface for type restrictions, you just can create one with the same Equals and GetHashCode methods and add it to any types, that you want to support.
public interface IKey
{
bool Equals(object value);
int GetHashCode();
}
public struct KeyStruct : IKey
{
}
public class KeyClass :IKey
{
}
public class MyDictionary<TKey, TValue> where TKey : IKey
{
}

Producing an abstract collection from an abstract collection

This issue has been bugging me for a while. Abstractly speaking, regardless of language, there are often situations when you want to have a method like this:
Collection method(Collection c) {
// select some elements from c based on some filter
// and return a new collection
}
Now, Collection is in this case some abstract class (Like say IList in C# or List in Java) with several implementations. I've been wondering what exactly is the right procedure to produce the abstract collection?
Is it ok to create a concrete collection inside the method and return it? Like:
Collection method(Collection c) {
Collection cc = new ConcreteCollection();
// select some elements from c based on some filter
return cc;
}
This of course puts a constraint on the resulting collection and will produce problems in case, for some reason, we want to cast the result of the method to a different concrete collection than the one used inside the method.
Or, use reflection to determine the actual concrete type of c and create an instance of that class:
Collection method(Collection c) {
Collection cc = c.getClass().newInstance();
// select some elements from c based on some filter
return cc;
}
For some reason this does not seem very "elegant" to me. I would greatly appreciate some insight in this matter.
(Speaking for java). The reason you're returning Collection (an interface) rather than a concrete type (such as ArrayList) is that you're telling the user that they shouldn't care about what the actual concrete type being used is. This leaves you free to choose the appropriate type for your library/api.
If you're enforcing a particular concrete class, then you should be returning that concrete class, rather than the interface.
So, they shouldn't be casting your return type to anything else other than Collection. See
When should I return the Interface and when the concrete class?.
In Java, there are actually some good examples of how to do this in the java.util.Collections class. Instead of taking a Collection and returning a Collection, the key methods take two collections, the "src" and the "dest". For example, Look at the signature of the copy method:
public static <T> void copy(List<? super T> dest, List<? extends T> src)
This puts the responsibility of instantiating the destination list on the caller.
I think you could do the same thing when you want to create a method that acts on a src Collection and puts the results into a destination Collection (rather than Lists).
I agree with Matthew Farwell's answer that you probably just want to return the interface and utilize that, but for the times when you really do need to work with a specific implementing class you can do it the same way the Collections class does it.
One approach you could take is to create a Collection implementation that delegates calls through to the original Collection. This defers the potentially expensive operation of filtering a large Collection until you need to explicitly read elements. It also saves memory.
Example
public interface Filter<T> {
boolean include(T t);
}
public class FilterCollection<T> implements Collection<T> {
private final Collection<T> orig;
private final Filter<T> filter;
public FilterCollection(Collection<T> orig, Filter<T> filter) {
this.orig = orig;
this.filter = filter;
}
public int size() {
int sz = 0;
for (T t : orig) {
if (filter.include(t)) {
++sz;
}
}
return sz;
}
public boolean contains(Object o) {
return o instanceof T && filter.include((T) o) && orig.contains(o);
}
public boolean add(T t) {
if (!filter.include(t)) {
throw new IllegalArgumentException("Element lies outside filter bounds.");
}
orig.add(t);
}
}
The caller should assume a given type of Collection is returned.
Instead it should either copy to the desired type or pass the desired type.
e.g.
Set<T> set2 = new HashSet<T>(filter(set));
List<T> list2 = new ArrayList<T>(filter(list));
or
filter(set2, set); // the target collection is passed.
filter(list2, list);
To the question about ConcreteCollection, it is definitely allowable.
To the concern about having a different concrete collection expected, there are a few ways to go around the problem:
Change the return type of the method. Example:
ConcreteCollection method(Collection c){
ConcreteCollection cc=new ConcreteCollection
for(Object x: c){
//do something
}
return cc
}
Make use of polymorphism. Example:
Collection x=method(c)
x.add(new Object) //add is a method defined within the abstract Collection
Use some utilities to cast the type. Example:
LinkedList h=Collections.toLinkedList(method(c))
Hoped my answer helped. ^^
As far as I can understand, you want to know how to make a method that accepts generic list and returns another modified generic list.
So, my advice will be to use an abstract type that implements method to modify its state.
IList<object> list = new List<object>();
list.Add(new object());
list.Remove(obj);
Or as showed above, instantiate a list that implements IList (or the Java equivalent) work with this instance and return the result as a IList
Edit
If you want to filter some item from a list to a new one, generics can help (I don't know if this feature exists in Java).
public IList<T> Filter<T>(IList<T> list)
{
var result = new List<T>();
result.Add(list[0]); // Or whatever filtering method
return result;
}
If you want your method to accept as many different collection types as possible, and you want to be sure that the result is the same implementation type as what you put in, you might want to use a void method which directly modifies the supplied collection. For instance:
import com.google.common.base.Predicate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class Testy {
private static <T> void filter(Iterable<T> collection, Predicate<T> filter) {
Iterator<T> iterator = collection.iterator();
while (iterator.hasNext()) {
if (!filter.apply(iterator.next())) { // Condition goes here
iterator.remove();
}
}
}
public static void main(String... args) {
List<String> list = new ArrayList<String>();
list.addAll(Arrays.asList("A", "B", "C", "D"));
filter(list, new Predicate<String>() { // Anonymous filter (predicate)
#Override public boolean apply(String input) {
return input.equals("B");
}
});
System.out.println(list); // Prints ["B"]
}
}
The helper method filter takes an Iterable, the simplest type required for iterating over something. Apply the filter to each element, and if the predicate (filter) returns false, remove that element from the underlying collection with Iterator.remove().
The Predicate<T> interface here comes from Google. You can easily write your own if you don't wish to import it. The only required method is apply(T) which returns a boolean. Either that, or just write your condition directly inside the loop and get rid of the second parameter.
This method is the most efficient if your original collection is mutable and you don't wish to keep any intermediate results.
Another option is to use Google Collections Collections2.filter(Collection<E>, Predicate<E>) which returns a Collection<E> just like in your question. Similarly, the Iterables class will do the same thing, but create lazy iterables where the filters are only applied when actually doing the iterating.

C# determining generic type

I have several templated objects that all implement the same interface:
I.E.
MyObject<datatype1> obj1;
MyObject<datatype2> obj2;
MyObject<datatype3> obj3;
I want to store these objects in a List... I think I would do that like this:
private List<MyObject<object>> _myList;
I then want to create a function that takes 1 parameter, being a datatype, to see if an object using that datatype exists in my list.... sorta clueless how to go about this. In Pseudo code it would be:
public bool Exist(DataType T)
{
return (does _myList contain a MyObject<T>?);
}
Some Clarification....
My interface is IMyObject<T>, my objects are MyObject<T>. I have a new class MyObjectManager which I need to have a List of MyObject<T> stored within. I need a function to check if a MyObject<T> exists in that list. The type T are datatypes which were auto-generated using T4.... POCO classes from my Entity Data Model.
You can make a generic function:
public bool Exists<T>() where T : class {
return _myList.OfType<MyObject<T>>().Any();
}
Note that this requires that you know T at compile-time.
If all you have is a System.Type object at runtime, you'll need to use reflection:
public bool Exists(Type t) {
var objectOfT = typeof(MyObject<>).MakeGenericType(t);
return _myList.Any(o => o.GetType() == objectOfT);
}
Note, however, that a List<MyObject<object>> cannot hold a MyObject<SomeType>.
You need to change the list to a List<object>, or make MyObject implement or inherit a non-generic type and make the list contain that type.
How about an extension method?
public static bool HasAny(this IEnumerable source, Type type) {
foreach (object item in source)
if (item != null && item.GetType().Equals(type))
return true;
return false;
}
Usage:
bool hasDataType1 = myList.HasAny(typeof(MyObject<datatype1>));
Note that if you don't want to have to type out typeof(...) -- i.e., if you basically want your Exist method to only care about objects of type MyObject<T>, I'd go with something like SLaks's answer:
public static bool Exist<T>(this IEnumerable source) {
return source.OfType<MyObject<T>>().Any();
}
Also, SLaks is right that you really can't have a List<MyObject<object>> that's full of anything other than objects of type MyObject<object> or some derived class (and MyObject<datatype1>, etc. do not derive from MyObject<object> -- generics don't work that way).
Another way I might suggest to work around the whole "you can't get the type of a generic class using a System.Type object without using reflection" issue would be this: Make your MyObject<T> implement a non-generic interface, like this:
public interface IMyObject {
Type DataType { get; }
}
public class MyObject<T> : IMyObject<T>, IMyObject {
public Type DataType {
get { return typeof(T); }
}
}
Then your list could be a List<IMyObject> (the non-generic interface) and your Exist method could look like this:
public static bool Exist<T>(this IEnumerable source, Type type) {
return source.OfType<IMyObject>().Any(x => x.DataType.Equals(type));
}
Since they all implement the same interface, instead of casting them to object and calling GetType (which can be expensive) why not add a property to your interface called class name (or something)? Then you can use the linq in order to grab that property. And don't forget using System.Linq
using System.Linq;
public bool Exist(List<IMyInterface> objects, IMyInterface typeToCheck)
{
return objects.Any(t => t.ObjectName == typeToCheck.ObjectName);
}

Categories