using HashSet removing duplicates
how can i remove duplicates using HashSet or if you have better idea please let me know but so far this is what i am doing...
i am trying to eliminate the duplicates and below code is what i am using....
HashSet<DropDownListClass> hashSetTopics = new HashSet<DropDownListClass>();
foreach (XmlNode node in topicNodes)
{
string topicId = node.Attributes["TopicId"].Value;
string topicName = node.Attributes["TopicName"].Value;
hashSetTopics.Add(new DropDownListClass { Id = topicId, Name = topicName });
}
the below code does removes the duplicates but the problem with the below is that i need a way to attach the id with name... at the end i am binding to dropdownlist.
HashSet<string> hashSetTopics1 = new HashSet<string>();
foreach (XmlNode node in topicNodes)
{
string topicId = node.Attributes["TopicId"].Value;
string topicName = node.Attributes["TopicName"].Value;
hashSetTopics1.Add(topicName });
}
DropDownList1.DataSource = hashSetTopics; /hashSetTopics1
DropDownList1.DataBind();
public class DropDownListClass
{
public string Id开发者_StackOverflow { get; set; }
public string Name { get; set; }
}
There are a couple of ways to do this.
One way would be to override the Equals
method of your DropDownListClass
. See Guidelines for Overriding Equals and Operator ==.
Another would be to create an EqualityComparer
derived class that does the comparison:
public DropDownComparer : EqualityComparer<DropDownListClass>
{
public override bool Equals(DropDownListClass i1, DropDownListClass i2)
{
bool rslt = (i1.Id == i2.Id) && (i1.Name == i2.Name);
}
public override int GetHashCode(DropDownListClass x)
{
return x.Id.GetHashCode() ^ x.Id.GetHashCode();
}
}
And when you create your HashSet
:
DropDownComparer comparer = new DropDownComparer();
HashSet<DropDownListClass> hashSetTopics = new HashSet<DropDownListClass>(comparer);
That tells the HashSet
code, "use my custom comparison function to compare items." Your first loop should work now.
IComparible interface (IEqualityComparer): http://msdn.microsoft.com/en-us/library/system.icomparable.aspx
you can use this code for generic equality projection
public sealed class ProjectionComparer<TValue, TProjection> : IEqualityComparer<TValue>
{
readonly Func<TValue, TProjection> _projection;
public ProjectionComparer(Func<TValue, TProjection> projection)
{
projection.AssertParameterNotNull("projection");
_projection = projection;
}
bool IEqualityComparer<TValue>.Equals(TValue x, TValue y)
{
var projectedX = _projection(x);
var projectedY = _projection(y);
return projectedX.Equals(projectedY);
}
int IEqualityComparer<TValue>.GetHashCode(TValue obj)
{
var projectedObj = _projection(obj);
return projectedObj.GetHashCode();
}
}
IList<ListItem> dropDownListItems = new List<ListItem>();
foreach (XmlNode node in topicNodes)
{
string topicId = node.Attributes["TopicId"].Value;
string topicName = node.Attributes["TopicName"].Value;
dropDownListItems.Add(new ListItem(topicName, topicId));
}
DropDownList1.DataSource = dropDownListItems.Distinct();
DropDownList1.DataBind();
EDIT I think you are getting dups in your HashSet because your the DropDownListClass isn't implementing IComparable
Below is an example of how duplicate data is making it's way into a HashSet. The MyObject class should probably implement the interfeace IComparible.
public void Main()
{
HashSet<MyObject> myObjects = new HashSet<MyObject>();
bool success = myObjects.Add(new MyObject{ID = 1});
success.Dump("First"); //Returns true
success = myObjects.Add(new MyObject{ID = 1});
success.Dump("Second"); //Returns true should have been false
}
// Define other methods and classes here
public class MyObject
{
public int ID {get; set;}
}
You can even call Distinct() off of your original HashSet object but that just hides that it's broken.
Try using a dictionary - you get uniqueness based on the key, and the value can be anything.
Dictionary<string, DropDownListClass> topics = new Dictionary<string, DropDownListClass>();
foreach (XmlNode node in topicNodes)
{
string topicId = node.Attributes["TopicId"].Value;
string topicName = node.Attributes["TopicName"].Value;
topics[topicName] = new DropDownListClass { Id = topicId, Name = topicName };
}
DropDownList1.DisplayMember = "Name";
DropDownList1.ValueMember = "Id";
DropDownList1.DataSource = topics.Values;
DropDownList1.DataBind();
You could also probably implement an Equals method on DropDownListClass that compared based on the Id property.
Lastly, DropDownListClass could probably have a much better name, such as Topic.
精彩评论