开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜